home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / macabuse / src / game.c.new < prev    next >
Encoding:
Text File  |  1997-05-20  |  70.3 KB  |  2,947 lines

  1. #include "idle.hpp"
  2. #include "system.h"
  3. #include "game.hpp"
  4. #include "dev.hpp"
  5. #include "id.hpp"
  6. #include "joy.hpp"
  7. #include "timing.hpp"
  8. #include "help.hpp"
  9. #include "ability.hpp"
  10. #include "cache.hpp"
  11. #include "loader.hpp"
  12. #include "lisp.hpp"
  13. #include "monoprnt.hpp"
  14. #include "jrand.hpp"
  15. #include "config.hpp"
  16. #include "light.hpp"
  17. #include "scroller.hpp"
  18. #include "dprint.hpp"
  19. #include "nfserver.hpp"
  20. #include "video.hpp"
  21. #include "transp.hpp"
  22. #include "clisp.hpp"
  23. #include "guistat.hpp"
  24. #include "menu.hpp"
  25. #include "gamma.hpp"
  26. #include "lisp_gc.hpp"
  27. #include "demo.hpp"
  28. #include "sbar.hpp"
  29. #include "profile.hpp"
  30. #include "compiled.hpp"
  31. #include "lisp_gc.hpp"
  32. #include "pmenu.hpp"
  33. #include "timing.hpp"
  34. #include "chat.hpp"
  35. #include "demo.hpp"
  36. #include "netcfg.hpp"
  37. #include "specache.hpp"
  38. #include "ant.hpp"
  39. #include "netstat.hpp"
  40.  
  41.  
  42. #ifdef __MAC__
  43. //#include <profiler.h>  //prof
  44. #include "macgame.hpp"
  45. #include "macstat.hpp"
  46. #endif
  47.  
  48. #include <ctype.h>
  49. #include <setjmp.h>
  50.  
  51. #define SHIFT_RIGHT_DEFAULT 0
  52. #define SHIFT_DOWN_DEFAULT 30
  53.  
  54. class game;
  55. extern crc_manager *net_crcs;
  56. extern void show_verinfo(int argc, char **argv);
  57. game *the_game;
  58. window_manager *eh=NULL;
  59. int dev,shift_down=SHIFT_DOWN_DEFAULT,shift_right=SHIFT_RIGHT_DEFAULT;
  60. double sum_diffs=1,total_diffs=12;
  61. int total_active=0;
  62. long map_xoff=0,map_yoff=0;
  63. long current_vxadd,current_vyadd;
  64. int frame_panic=0,massive_frame_panic=0;
  65. int demo_start=0,idle_ticks=0;
  66. int req_end=0;
  67.  
  68. extern palette *old_pal;
  69. char **start_argv;
  70. int start_argc;
  71. int has_joystick=0;
  72. char req_name[100];
  73.  
  74. int registered=0;
  75.  
  76. extern int PixMult;
  77.  
  78. extern uchar chatting_enabled;
  79.  
  80. extern int confirm_quit();
  81.  
  82. #ifdef __MAC__
  83. extern char *macify_name(char *s);
  84.  
  85. #if 1
  86. #include "atalk.hpp"
  87. atalk_protocol atalk;
  88.  
  89. #else
  90. #include "tcpip.hpp"
  91.  
  92. tcpip_protocol tcpip;
  93. #endif
  94.  
  95. #endif
  96.  
  97.  
  98. #if !defined (MAC_PROFILE)
  99. #define StartTime(a) (0)
  100. #define DiffTime(a,b) (0)
  101. #else
  102.  
  103. // Timer code
  104. #include <Timer.h> // kill me (us)
  105.  
  106. #define KJCOUNTERS 20
  107. long kjcount[KJCOUNTERS];
  108. char kjfie[KJCOUNTERS][256] = { };  // kill me
  109.  
  110. extern long StartTime(int cnt);         //kill me
  111. extern long DiffTime(char *name, int cnt);   //kill me
  112. extern unsigned lighting_loop_time;
  113.  
  114. long StartTime(int cnt) //kill me too
  115. {
  116.   UnsignedWide t;
  117.   Microseconds(&t);
  118.     
  119.   return (kjcount[cnt] = t.lo);
  120. }
  121.  
  122. long DiffTime(char *name, int cnt) //kill me too
  123. {
  124.   UnsignedWide t;
  125.   Microseconds(&t);
  126.     
  127.   sprintf(kjfie[cnt],"%-16s %8d",name,t.lo-kjcount[cnt]);
  128.     
  129.   return (t.lo-kjcount[cnt]);
  130.  
  131. }
  132. #endif
  133.  
  134. void fade_in(image *im, int steps);
  135. void fade_out(int steps);
  136.  
  137. FILE *open_FILE(char *filename, char *mode)
  138. {
  139.   /*  char *prefix=get_filename_prefix() ? get_filename_prefix() : "",*c;
  140.   
  141.       if (get_save_filename_prefix)
  142.       {
  143.       for (c=mode;*c;c++) 
  144.       if (c=='w' || c=='W') 
  145.       {
  146.       }
  147.       } */
  148.       
  149.   
  150.   char tmp_name[200];
  151.   if (get_filename_prefix())
  152.     sprintf(tmp_name,"%s%s",get_filename_prefix(),filename);
  153.   else strcpy(tmp_name,filename);
  154. #ifdef __MAC__
  155.   macify_name(tmp_name);
  156. #endif
  157.   return fopen(tmp_name,mode);
  158. }
  159.  
  160.  
  161. void handle_no_space()
  162. {
  163.   char *no_space_msg= "\nYou are out of disk space or the game\n"
  164.     "was unable to write to disk for some reason\n"
  165.     "The game cannot continue, please check this out\n"
  166.     "and try again.\n";
  167.   if (eh)
  168.   {
  169.     jwindow *no_space=eh->new_window(0,0,-1,-1,
  170.         new button(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP,ID_QUIT_OK,"Quit",
  171.             new info_field(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP+eh->font()->height()*2,ID_NULL,
  172.                 no_space_msg,NULL)),"ERROR");
  173.     event ev;
  174.     do 
  175.     { 
  176.       eh->flush_screen();
  177.       eh->get_event(ev);
  178.     } while (ev.type!=EV_MESSAGE || ev.message.id!=ID_QUIT_OK);
  179.     eh->close_window(no_space);
  180.  
  181.     close_graphics();
  182.     exit(1);
  183.   } else
  184.   {
  185.     dprintf("%s\n",no_space_msg);
  186.     exit(0);
  187.   }
  188. }
  189.  
  190. void game::play_sound(int id, int vol, long x, long y)
  191. {
  192.   if (sound_avail&SFX_INITIALIZED)
  193.   {
  194.     if (vol<15) return ;
  195.     if (!player_list) return ;
  196.  
  197.     ulong mdist=0xffffffff;
  198.     view *cd=NULL;
  199.     for (view *f=player_list;f;f=f->next)
  200.     {
  201.       if (f->local_player())
  202.       {
  203.     long cx=abs(f->x_center()-x),cy=abs(f->y_center()-y),d;
  204.     if (cx<cy)
  205.           d=cx+cy-(cx>>1);
  206.     else d=cx+cy-(cy>>1);
  207.  
  208.     if (d<mdist)
  209.     {
  210.       cd=f;
  211.       mdist=d;
  212.     } 
  213.       }
  214.     }  
  215.     if (mdist>500 || !cd) return ;
  216.     if (mdist<100) mdist=0;
  217.     else mdist-=100;
  218.  
  219.     int v=(400-mdist)*sfx_volume/400-(127-vol);
  220.     if (v>0 && (sound_avail&SFX_INITIALIZED))
  221.       cash.sfx(id)->play(v);
  222.   }
  223. }
  224.  
  225. int get_option(char *name)
  226. {
  227.   int i;
  228.   for (i=1;i<start_argc;i++)
  229.     if (!strcmp(start_argv[i],name))
  230.       return i;
  231.   return 0;
  232. }
  233.  
  234.  
  235. void make_screen_size(int w, int h)
  236. {
  237.   return ;
  238.   /*
  239.   for (view *f=player_list;f;f=f->next)
  240.   {
  241.     if (f->local_player())
  242.     {
  243.       if (w>=xres-1) w=xres-2;
  244.       if (h>=yres-1) h=yres-2;
  245.       f->suggest.cx1=(xres+1)/2-w/2;
  246.       f->suggest.cx2=(xres+1)/2+w/2;
  247.       f->suggest.cy1=(yres-31)/2+5-h/2;
  248.       f->suggest.cy2=(yres-51)/2+5+h/2;
  249.       f->suggest.shift_down=f->shift_down;
  250.       f->suggest.shift_right=f->shift_right;
  251.       f->suggest.pan_x=f->pan_x;
  252.       f->suggest.pan_y=f->pan_y;
  253.  
  254.       f->suggest.send_view=1;
  255.     }
  256.   } */
  257. }
  258.  
  259. void game::grow_views(int amount)
  260. {
  261.   return ;
  262.   /*
  263.   int undo=0;
  264.   view *f=first_view;
  265.   for (;f;f=f->next)
  266.   {
  267.     if (f->local_player())
  268.     {
  269.       f->suggest.cx1=(f->cx1-amount);
  270.       f->suggest.cy1=f->cy1-amount/2;
  271.       f->suggest.cx2=(f->cx2+amount);
  272.       f->suggest.cy2=f->cy2+amount/2;
  273.       f->suggest.shift_down=f->shift_down;
  274.       f->suggest.shift_right=f->shift_right;
  275.       f->suggest.pan_x=f->pan_x;
  276.       f->suggest.pan_y=f->pan_y;
  277.  
  278.       f->suggest.send_view=1;
  279.     }
  280.   }
  281.  
  282.  
  283.   for (f=first_view;f;f=f->next)  
  284.   {
  285.     if (f->local_player())
  286.     {
  287.       if (f->suggest.cx2-f->suggest.cx1<20 || f->suggest.cy2-f->suggest.cy1<15 || 
  288.           f->suggest.cx1<0 || f->suggest.cy1<0) f->suggest.send_view=0;
  289.       if (f->next && f->next->local_player() && f->suggest.cy2>=f->next->cy1) f->suggest.send_view=0;
  290.     }
  291.   } */
  292. }
  293.  
  294. void game::pan(int xv, int yv) 
  295.   first_view->pan_x+=xv; 
  296.   first_view->pan_y+=yv; 
  297. }
  298.  
  299. view *game::view_in(int mousex, int mousey)
  300. {
  301.   for (view *f=first_view;f;f=f->next)
  302.     if (f->drawable() && mousex>=f->cx1 && mousey>=f->cy1 && mousex<=f->cx2 && mousey<=f->cy2)
  303.       return f;
  304.   return NULL;
  305. }
  306.  
  307. int playing_state(int state)
  308.   if (state==RUN_STATE || state==PAUSE_STATE) return 1;
  309.   else return 0;
  310. }
  311.  
  312. void game::ftile_on(int screenx, int screeny, long &x, long &y)
  313. {
  314.   mouse_to_game(screenx,screeny,x,y);
  315.   x/=ftile_width();
  316.   y/=ftile_height();
  317.   /*  view *f=view_in(screenx,screeny);
  318.       if (f)
  319.       {
  320.       x=((long)(screenx)-(long)f->cx1+f->xoff())/(long)f_wid;
  321.       y=((long)(screeny)-(long)f->cy1+f->yoff())/(long)f_hi;
  322.       }
  323.       else
  324.       {
  325.       x=-1; 
  326.       y=-1;
  327.       }*/
  328. }
  329.  
  330. void game::btile_on(int screenx, int screeny, long &x, long &y)
  331. {
  332.   view *f=view_in(screenx,screeny);
  333.   if (f)
  334.   {
  335.     x=((long)(screenx)-(long)f->cx1+f->xoff()*bg_xmul/bg_xdiv)/(long)b_wid; 
  336.     y=((long)(screeny)-(long)f->cy1+f->yoff()*bg_ymul/bg_ydiv)/(long)b_hi;
  337.   }
  338.   else
  339.   {
  340.     x=-1; 
  341.     y=-1;
  342.   }
  343. }
  344.  
  345.  
  346. void game::mouse_to_game(long x, long y, long &gamex, long &gamey, view *f)
  347. {
  348.   if (!f)
  349.   {
  350.     f=view_in(x,y);
  351.     if (!f) f=player_list;  // if not in a view use the first on
  352.   }
  353.  
  354.   if (f)
  355.   {
  356.     if (dev&MAP_MODE)
  357.     {
  358.       gamex=((x-(long)f->cx1)*ftile_width()/AUTOTILE_WIDTH+map_xoff*ftile_width());
  359.       gamey=((y-(long)f->cy1)*ftile_height()/AUTOTILE_HEIGHT+map_yoff*ftile_height());
  360.     } else
  361.     {
  362.       gamex=(x-(long)f->cx1+f->xoff());
  363.       gamey=(y-(long)f->cy1+f->yoff());
  364.     }
  365.   }
  366. }
  367.  
  368. void game::game_to_mouse(long gamex, long gamey, view *which, long &x, long &y)
  369. {
  370.   if (dev&MAP_MODE)
  371.   {
  372.     long x1,y1;
  373.     if (dev&EDIT_MODE)
  374.     {
  375.       x1=map_xoff;
  376.       y1=map_yoff;
  377.     } else
  378.     {
  379.       if (which->focus)
  380.       {
  381.     x1=which->focus->x/ftile_width()-(which->cx2-which->cx1)/AUTOTILE_WIDTH/2;
  382.     y1=which->focus->y/ftile_height()-(which->cy2-which->cy1)/AUTOTILE_HEIGHT/2;
  383.       } else x1=y1=0;
  384.     }
  385.     if (x1<0) x1=0;
  386.     if (y1<0) y1=0;
  387.  
  388.     x=gamex*AUTOTILE_WIDTH/ftile_width()-x1*AUTOTILE_WIDTH+which->cx1;
  389.     if (x1>0)
  390.       x-=((which->focus->x*AUTOTILE_WIDTH/ftile_width()) %AUTOTILE_WIDTH);
  391.  
  392.     y=gamey*AUTOTILE_HEIGHT/ftile_height()-y1*AUTOTILE_HEIGHT+which->cy1;
  393.     if (y1>0)
  394.       y-=((which->focus->y*AUTOTILE_HEIGHT/ftile_height()) %AUTOTILE_HEIGHT);
  395.   }
  396.   else
  397.   {
  398.     x=gamex-which->xoff()+which->cx1;
  399.     y=gamey-which->yoff()+which->cy1;
  400.   }
  401. }
  402.  
  403. int window_state(int state)
  404. {
  405.   switch (state)
  406.   {
  407.     case RUN_STATE : 
  408.     case PAUSE_STATE : 
  409.     case JOY_CALB_STATE :
  410.     { return 1; } break;
  411.  
  412.     case INTRO_START_STATE :
  413.     case HELP_STATE : 
  414.     case INTRO_MORPH_STATE :
  415.     case MENU_STATE :
  416.     case SCENE_STATE :
  417.     { return 0; } break;
  418.   }
  419.   return 1;
  420. }
  421.  
  422.  
  423. // not global for now
  424. extern void make_edit_mode_menu();
  425. extern void kill_edit_mode_menu();
  426.  
  427. void game::set_state(int new_state) 
  428. {
  429.   int d=0;
  430.   
  431.   reset_keymap();                             // we think all the keys are up right now
  432.  
  433.   if (!playing_state(new_state) && playing_state(state))
  434.   {
  435.     switch_mode(VMODE_640x480);
  436.   }
  437.  
  438.   if (playing_state(new_state) && !playing_state(state))
  439.   {
  440.     switch_mode(VMODE_320x200);
  441.     recalc_local_view_space();
  442.  
  443.     if (first_view && first_view!=player_list)
  444.     {
  445.       while (first_view)
  446.       {
  447.         view *tmp=first_view;
  448.         first_view=first_view->next;
  449.         delete tmp;
  450.       }
  451.       first_view=old_view;
  452.       old_view=NULL;
  453.     }
  454.     first_view=player_list;
  455.     d=1;
  456.   } else if (!playing_state(new_state) && (playing_state(state) || state==START_STATE))
  457.   {
  458.     if (player_list)    
  459.     {
  460.       first_view=new view(player_list->focus,NULL,-1);
  461.       first_view->pan_x=player_list->xoff();
  462.       first_view->pan_y=player_list->yoff();
  463.     }
  464.     else    
  465.       first_view=new view(NULL,NULL,0);
  466.  
  467.     /*
  468.     first_view->cx1=(xres+1)/2-155;
  469.     first_view->cy1=(yres+1)/2-95;
  470.     first_view->cx2=(xres+1)/2+155;
  471.     if (total_weapons)
  472.       first_view->cy2=(yres+1)/2+68;
  473.     else
  474.       first_view->cy2=(yres+1)/2+95;
  475.       */
  476.     
  477.     d=1;
  478.   }
  479.   
  480.  
  481.  
  482.   // switching to/from scene mode cause the screen size to change and the border to change
  483.   // so we need to redraw.
  484.   if (window_state(new_state) && !window_state(state))
  485.     eh->show_windows();
  486.   else if (!window_state(new_state) && window_state(state))
  487.     eh->hide_windows();
  488.  
  489.   int old_state=state;
  490.   state=new_state;
  491.  
  492.   pal->load();    // restore old palette
  493.  
  494.   if (playing_state(state) &&  !(dev&EDIT_MODE))
  495.     eh->set_mouse_shape(cash.img(c_target)->copy(),8,8);
  496.   else
  497.     eh->set_mouse_shape(cash.img(c_normal)->copy(),1,1);
  498.  
  499.     if (playing_state(new_state) && (dev&EDIT_MODE))
  500.         make_edit_mode_menu();
  501.     else
  502.         kill_edit_mode_menu();
  503.     
  504.   if (old_state==SCENE_STATE && new_state!=SCENE_STATE)
  505.   {
  506.     d=1;
  507.     scene_director.set_abort(0);   // don't skip any more scene stuff
  508.   }
  509.   else if (new_state==SCENE_STATE && old_state!=SCENE_STATE)
  510.     d=1;
  511.   
  512.   if (d)
  513.     draw(state==SCENE_STATE);
  514.  
  515.   dev_cont->set_state(new_state);
  516. }
  517.  
  518. void game::joy_calb(event &ev)
  519. {
  520.   if (joy_win)   // make sure the joy stick calibration window is open
  521.   {
  522.     
  523.     if (ev.type==EV_SPURIOUS)   // spurious means we should update your status
  524.     {
  525.       int b1,b2,b3=0,x,y;
  526.       joy_status(b1,b2,b2,x,y);
  527.       int but=b1|b2|b3;
  528.       if (x>0) x=1; else if (x<0) x=-1;
  529.       if (y>0) y=1; else if (y<0) y=-1;
  530.       if (but) but=1;
  531.       int dx=WINDOW_FRAME_LEFT+20,dy=WINDOW_FRAME_TOP+5;
  532.       image *jim=cash.img(joy_picts[but*9+(y+1)*3+x+1]);
  533.       joy_win->screen->bar(dx,dy,dx+jim->width()+6,dy+jim->height()+6,eh->black());
  534.       jim->put_image(joy_win->screen,dx+3,dy+3);
  535.  
  536.       if (but)
  537.         joy_calibrate();
  538.     } else if (ev.type==EV_MESSAGE && ev.message.id==JOY_OK)
  539.     {
  540.       eh->close_window(joy_win);
  541.       joy_win=NULL;
  542.       set_state(MENU_STATE);
  543.     }        
  544.   }
  545. }
  546.  
  547. void game::menu_select(event &ev)
  548. {
  549.   state=DEV_MOUSE_RELEASE;
  550.   if (top_menu)
  551.   {
  552.     /*    eh->push_event(new event(men_mess[((pick_list *)ev.message.data)->get_selection()],NULL));
  553.           eh->close_window(top_menu);
  554.           top_menu=NULL;*/
  555.   }
  556. }
  557.  
  558.  
  559. void game::show_help(char *st)
  560. {
  561.   strcpy(help_text,st);
  562.   help_text_frames=0;  
  563.   refresh=1;
  564. }
  565.  
  566. void game::draw_value(image *screen, int x, int y, int w, int h, int val, int max)
  567. {
  568.   screen->bar(x,y,x+w-1,y+h,eh->dark_color());
  569.   screen->bar(x,y+1,x+w*val/max,y+h-1,eh->bright_color());  
  570. }
  571.  
  572.  
  573. void game::set_level(level *nl)
  574. {
  575.   if (current_level) 
  576.     delete current_level;  
  577.   current_level=nl;
  578. }
  579.  
  580. void game::load_level(char *name)
  581. {
  582.   if (current_level) 
  583.     delete current_level;
  584.  
  585.   bFILE *fp=open_file(name,"rb");
  586.  
  587.   if (fp->open_failure())
  588.   {
  589.     delete fp;
  590.     current_level=new level(100,100,name);
  591.     char msg[100];
  592.     sprintf(msg,symbol_str("no_file"),name);
  593.     show_help(msg);
  594.   }
  595.   else
  596.   {                  
  597.     spec_directory sd(fp);  
  598.  
  599. #ifdef __MAC__
  600.  
  601.     if (state != RUN_STATE)
  602.     {
  603.       // clear screen
  604.       image blank(2,2); blank.clear();
  605.       fade_out(16);
  606.       eh->set_mouse_shape(blank.copy(),0,0);      // don't show mouse
  607.       fade_in(cash.img(cdc_logo),16);
  608.     }
  609. #endif
  610.  
  611.     spec_entry *e=sd.find("Copyright 1995 Crack dot Com, All Rights reserved"); 
  612.     if (!e)
  613.     { 
  614.       the_game->show_help(symbol_str("missing_c"));
  615.       current_level=new level(100,100,"untitled");
  616.       the_game->need_refresh();
  617.     }
  618.     else 
  619.       current_level=new level(&sd,fp,name);
  620.     delete fp;
  621.   }
  622.   
  623.   base->current_tick=(current_level->tick_counter()&0xff); 
  624.  
  625.   current_level->level_loaded_notify();
  626.   the_game->help_text_frames=0;  
  627.  
  628. }
  629.  
  630. int game::done() 
  631.   return finished || (main_net_cfg && main_net_cfg->restart_state());
  632.  
  633. }
  634.  
  635. void game::end_session()
  636. {
  637.   finished=1;
  638.   if (main_net_cfg)
  639.   {
  640.     delete main_net_cfg;
  641.     main_net_cfg=NULL;
  642.   }
  643. }
  644.  
  645. void game::put_block_fg(int x, int y, trans_image *im)
  646. {
  647.   for (view *f=first_view;f;f=f->next)
  648.   {
  649.     if (f->drawable())
  650.     {
  651.       int xoff=f->xoff(),yoff=f->yoff(),viewx1=f->cx1,viewy1=f->cy1,viewx2=f->cx2,viewy2=f->cy2;
  652.       if (xoff/ftile_width()>x || xoff/ftile_width()+(viewx2-viewx1)/ftile_width()+1<x ||
  653.       yoff/ftile_height()>y || yoff/ftile_height()+(viewy2-viewy1)/ftile_height()+1<y) return;
  654.       short cx1,cy1,cx2,cy2;
  655.       screen->get_clip(cx1,cy1,cx2,cy2);
  656.       screen->set_clip(viewx1,viewy1,viewx2,viewy2);
  657.       im->put_image(screen,(x-xoff/ftile_width())*ftile_width()+viewx1-xoff%ftile_width(),
  658.           (y-yoff/ftile_height())*ftile_height()+viewy1-yoff%ftile_height());
  659.       screen->set_clip(cx1,cy1,cx2,cy2);
  660.     }
  661.   }
  662. }
  663.  
  664. void game::put_block_bg(int x, int y, image *im)
  665. {
  666.   for (view *f=first_view;f;f=f->next)
  667.   {
  668.     if (f->drawable())
  669.     {
  670.       int xoff=f->xoff(),yoff=f->yoff(),viewx1=f->cx1,viewy1=f->cy1,viewx2=f->cx2,viewy2=f->cy2;
  671.       int xo=xoff*bg_xmul/bg_xdiv;
  672.       int yo=yoff*bg_ymul/bg_ydiv;
  673.       
  674.       if (xo/btile_width()>x || xo/btile_width()+(viewx2-viewx1)/btile_width()+1<x ||
  675.       yo/btile_height()>y || yo/btile_height()+(viewy2-viewy1)/btile_height()+1<y) return;
  676.       short cx1,cy1,cx2,cy2;
  677.       screen->get_clip(cx1,cy1,cx2,cy2);
  678.       screen->set_clip(viewx1,viewy1,viewx2,viewy2);
  679.       im->put_image(screen,(x-xo/btile_width())*btile_width()+viewx1-xo%btile_width(),
  680.           (y-yo/btile_height())*btile_height()+viewy1-yo%btile_height(),0);
  681.       screen->set_clip(cx1,cy1,cx2,cy2);
  682.     }
  683.   }
  684. }
  685.  
  686. int need_delay=1;
  687.  
  688. void game::dev_scroll()
  689. {
  690.   need_delay=0;
  691.   if (dev)
  692.   {
  693.     int xmargin,ymargin;
  694.     if (xres>400)
  695.     {
  696.       xmargin=20;
  697.       ymargin=10;
  698.     }
  699.     else 
  700.     {
  701.       xmargin=10;
  702.       ymargin=5;
  703.     }
  704.  
  705.     int xs,ys;
  706.     if (mousex<xmargin &&  dev_cont->ok_to_scroll()) xs=-18;
  707.     else if (mousex>(screen->width()-xmargin) &&  dev_cont->ok_to_scroll()) xs=18;
  708.     else if (eh->key_pressed(JK_LEFT) && !last_input && !dev_cont->need_arrows())
  709.       xs=-18;
  710.     else if (eh->key_pressed(JK_RIGHT) && !last_input && !dev_cont->need_arrows())
  711.       xs=18;
  712.     else xs=0;
  713.          
  714.  
  715.     if (mousey<ymargin && dev_cont->ok_to_scroll()) ys=-18;
  716.     else if (mousey>(screen->height()-ymargin) &&  dev_cont->ok_to_scroll()) ys=18;
  717.     else if (eh->key_pressed(JK_UP) && !last_input)
  718.       ys=-18;
  719.     else if (eh->key_pressed(JK_DOWN) && !last_input)
  720.       ys=18;
  721.     else ys=0;
  722.  
  723.     
  724.     if (xs || ys)
  725.     {
  726.       need_delay=1;
  727.       if (dev&MAP_MODE)
  728.       {
  729.         map_xoff+=xs/2;
  730.         map_yoff+=ys/2;
  731.         if (map_xoff<0) map_xoff=0;
  732.         if (map_yoff<0) map_yoff=0;
  733.       } 
  734.       else
  735.       { 
  736.         for (view *v=first_view;v;v=v->next)
  737.         {
  738.           if (xs>=0 || v->xoff()>0)
  739.             v->pan_x+=xs;
  740.           if (ys>=0 || v->yoff()>0)
  741.             v->pan_y+=ys;
  742.         }
  743.       }
  744.       refresh=1;
  745.     }
  746.   }
  747. }
  748.  
  749. void remap_area(image *screen, int x1, int y1, int x2, int y2, uchar *remap)
  750. {
  751.   uchar *sl=(uchar *)screen->scan_line(y1)+x1;
  752.   int x,y,a=screen->width()-(x2-x1+1);
  753.   uchar c;
  754.   for (y=y1;y<=y2;y++)
  755.   {
  756.     for (x=x1;x<=x2;x++)
  757.     {
  758.       c=*sl;
  759.       *(sl++)=remap[c];
  760.     }
  761.     sl+=a;
  762.   }
  763. }
  764.  
  765. void post_render()
  766. {
  767.   if (DEFINEDP(symbol_function(l_post_render)))
  768.   {
  769.     screen->dirt_off();
  770.     clear_tmp();
  771.     eval_function((lisp_symbol *)l_post_render,NULL);
  772.     clear_tmp();
  773.     screen->dirt_on();
  774.   }
  775. }
  776.   
  777. void game::draw_map(view *v, int interpolate)
  778. {
  779.   foretile *ft;
  780.   backtile *bt;
  781.   int x1,y1,x2,y2,x,y,xo,yo,nxoff,nyoff;
  782.   short cx1,cy1,cx2,cy2;
  783.   
  784.   StartTime(6); //kill me
  785.   
  786.   screen->get_clip(cx1,cy1,cx2,cy2);
  787.  
  788.   if (!current_level || state==MENU_STATE)
  789.   {
  790.     if (title_screen>=0)
  791.     {
  792.       if (state==SCENE_STATE)
  793.         screen->set_clip(v->cx1,v->cy1,v->cx2,v->cy2);        
  794.       image *tit=cash.img(title_screen);
  795.       tit->put_image(screen,screen->width()/2-tit->width()/2,
  796.           screen->height()/2-tit->height()/2);
  797.       if (state==SCENE_STATE)
  798.         screen->set_clip(cx1,cy1,cx2,cy2);
  799.       eh->flush_screen();
  800.     }   
  801.     return ;
  802.   }
  803.  
  804.   refresh=0;  
  805.  
  806.  
  807.   // save the dirty rect routines some work by markinging evrything in the 
  808.   // view area dirty alreadt
  809.  
  810.   if (small_render)
  811.     screen->add_dirty(v->cx1,v->cy1,(v->cx2-v->cx1+1)*2+v->cx1,v->cy1+(v->cy2-v->cy1+1)*2);    
  812.   else
  813.     screen->add_dirty(v->cx1,v->cy1,v->cx2,v->cy2);    
  814.  
  815.   if (v->draw_solid!=-1)      // fill the screen and exit..
  816.   {
  817.     int c=v->draw_solid;
  818.     for (int y=v->cy1;y<=v->cy2;y++)
  819.       memset(screen->scan_line(y)+v->cx1,c,v->cx2-v->cx1+1);
  820.     v->draw_solid=-1;
  821.     return ;
  822.   }
  823.  
  824.   long old_cx1,old_cy1,old_cx2,old_cy2;   // if we do a small render, we need to restore these
  825.   image *old_screen=NULL;
  826.   if (small_render && (dev&DRAW_LIGHTS))  // cannot do this if we skip lighting
  827.   {
  828.     old_cx1=v->cx1;
  829.     old_cy1=v->cy1;
  830.     old_cx2=v->cx2;
  831.     old_cy2=v->cy2;
  832.  
  833.     /*    v->cx1=0;
  834.     v->cy1=0;
  835.     v->cx2=small_render->width()-1;
  836.     v->cy2=small_render->height()-1; */
  837.  
  838.     old_screen=screen;
  839.     screen=small_render;
  840.   } else
  841.     screen->dirt_off();
  842.  
  843.  
  844.  
  845.   //  long max_xoff=(current_level->foreground_width()-1)*ftile_width()-(v->cx2-v->cx1+1);
  846.   //  long max_yoff=(current_level->foreground_height()-1)*ftile_height()-(v->cy2-v->cy1+1); 
  847.  
  848.   long xoff,yoff;
  849.   if (interpolate)
  850.   {
  851.     xoff=v->interpolated_xoff();
  852.     yoff=v->interpolated_yoff();
  853.   } else
  854.   {
  855.     xoff=v->xoff();
  856.     yoff=v->yoff();
  857.   }
  858.  
  859.   //  if (xoff>max_xoff) xoff=max_xoff;
  860.   //  if (yoff>max_yoff) yoff=max_yoff;  
  861.  
  862.   current_vxadd=xoff-v->cx1;
  863.   current_vyadd=yoff-v->cy1;
  864.  
  865.   screen->set_clip(v->cx1,v->cy1,v->cx2,v->cy2);
  866.  
  867.   nxoff=xoff*bg_xmul/bg_xdiv;
  868.   nyoff=yoff*bg_ymul/bg_ydiv;
  869.  
  870.   //  long max_bg_xoff=(current_level->background_width())*btile_width()-(v->cx2-v->cx1+1);
  871.   //  long max_bg_yoff=(current_level->background_height())*btile_height()-(v->cy2-v->cy1+1);
  872.   //  if (nxoff>max_bg_xoff) nxoff=max_xoff;
  873.   //  if (nyoff>max_bg_yoff) nyoff=max_yoff;  
  874.   
  875.   
  876.   x1=nxoff/btile_width(); y1=nyoff/btile_height();
  877.   x2=x1+(v->cx2-v->cx1+btile_width())/btile_width();
  878.   y2=y1+(v->cy2-v->cy1+btile_height())/btile_height();
  879.  
  880.  
  881.   xo=v->cx1-nxoff%btile_width();
  882.   yo=v->cy1-nyoff%btile_height();
  883.   
  884.   int xinc,yinc,draw_x,draw_y;
  885.  
  886.  
  887.   DiffTime("      PreDraw",6);//kill me
  888.   StartTime(7); //kill me
  889.   if (!(dev & MAP_MODE) && (dev & DRAW_BG_LAYER))
  890.   {
  891.     xinc=btile_width();  
  892.     yinc=btile_height();  
  893.     
  894.     int bh=current_level->background_height(),bw=current_level->background_width();
  895.     ushort *bl;
  896.     for (draw_y=yo,y=y1;y<=y2;y++,draw_y+=yinc)
  897.     {
  898.       if (y>=bh)
  899.         bl=NULL;
  900.       else
  901.         bl=current_level->get_bgline(y)+x1;
  902.  
  903.       for (x=x1,draw_x=xo;x<=x2;x++,draw_x+=xinc)
  904.       {
  905.         if (x<bw && y<bh)
  906.         {
  907.           bt=get_bg(*bl);
  908.           bl++;
  909.         }
  910.         else bt=get_bg(0);
  911.  
  912.         bt->im->put_image(screen,draw_x,draw_y); 
  913.         //        if (!(dev & EDIT_MODE) && bt->next)
  914.         //      current_level->put_bg(x,y,bt->next);
  915.       }
  916.     }
  917.   }
  918.   //  if (!(dev&EDIT_MODE))
  919.   //    server_check();
  920.  
  921.   uchar rescan=0;  
  922.  
  923.   int fw,fh;
  924.  
  925.   if (dev&MAP_MODE)
  926.   {
  927.     fw=AUTOTILE_WIDTH;
  928.     fh=AUTOTILE_HEIGHT;
  929.     if (dev&EDIT_MODE)
  930.     {
  931.       x1=map_xoff;
  932.       y1=map_yoff;
  933.     } else
  934.     {
  935.       if (v->focus)
  936.       {
  937.         x1=v->focus->x/ftile_width()-(v->cx2-v->cx1)/fw/2;
  938.         y1=v->focus->y/ftile_height()-(v->cy2-v->cy1)/fh/2;
  939.       } else x1=y1=0;
  940.     }
  941.     if (x1>0)
  942.       xo=v->cx1-((v->focus->x*fw/ftile_width()) %fw);
  943.     else xo=v->cx1;
  944.     if (y1>0)
  945.       yo=v->cy1-((v->focus->y*fh/ftile_height()) %fh);
  946.     else yo=v->cy1;
  947.   } else
  948.   {
  949.     fw=ftile_width();
  950.     fh=ftile_height();
  951.     x1=(xoff)/fw; y1=(yoff)/fh;
  952.     xo=v->cx1-xoff%fw;
  953.     yo=v->cy1-yoff%fh;
  954.  
  955.   }
  956.   if (x1<0) x1=0;
  957.   if (y1<0) y1=0;
  958.   
  959.   x2=x1+(v->cx2-v->cx1+fw)/fw;
  960.   y2=y1+(v->cy2-v->cy1+fh)/fh;
  961.   if (x2>=current_level->foreground_width())
  962.     x2=current_level->foreground_width()-1;
  963.   if (y2>=current_level->foreground_height())
  964.     y2=current_level->foreground_height()-1;
  965.  
  966.  
  967.   xinc=fw;
  968.   yinc=fh;
  969.  
  970.   DiffTime("      BG/MAP",7);//kill me
  971.   StartTime(8); //kill me
  972.  
  973.   if (dev & DRAW_FG_LAYER)
  974.   {
  975.     short ncx1,ncy1,ncx2,ncy2;
  976.     screen->get_clip(ncx1,ncy1,ncx2,ncy2);
  977.  
  978.     int scr_w=screen->width();
  979.     if (dev&MAP_MODE)
  980.     {
  981.       if (dev&EDIT_MODE)
  982.         screen->clear(eh->bright_color());
  983.       else
  984.         screen->clear(eh->black());
  985.       for (y=y1,draw_y=yo;y<=y2;y++,draw_y+=yinc)
  986.       {
  987.         if (!(draw_y<ncy1 ||draw_y+yinc>=ncy2))
  988.         {
  989.           ushort *cl=current_level->get_fgline(y)+x1;
  990.           uchar *sl1=screen->scan_line(draw_y)+xo;
  991.           for (x=x1,draw_x=xo;x<=x2;x++,cl++,sl1+=xinc,draw_x+=xinc)
  992.           {
  993.             if (!(draw_x<ncx1 || draw_x+xinc>=ncx2))
  994.             {
  995.               int fort_num;
  996.               //          if (*cl&0x8000 || (dev&EDIT_MODE))
  997.               fort_num=fgvalue(*cl);
  998.               //          else fort_num=0;
  999.             
  1000.               uchar *sl2=get_fg(fort_num)->micro_image->scan_line(0);
  1001.               uchar *sl3=sl1;
  1002.               memcpy(sl3,sl2,AUTOTILE_WIDTH); sl2+=AUTOTILE_WIDTH; sl3+=scr_w;
  1003.               memcpy(sl3,sl2,AUTOTILE_WIDTH); sl2+=AUTOTILE_WIDTH; sl3+=scr_w;
  1004.               memcpy(sl3,sl2,AUTOTILE_WIDTH);
  1005.             }
  1006.           }
  1007.         }
  1008.       }
  1009.  
  1010.       if (dev&EDIT_MODE)
  1011.         current_level->draw_areas(v);
  1012.     } else
  1013.     {
  1014.  
  1015.       int fg_h=current_level->foreground_height(),fg_w=current_level->foreground_width();
  1016.       
  1017.       for (y=y1,draw_y=yo;y<=y2;y++,draw_y+=yinc)
  1018.       {
  1019.     
  1020.         ushort *cl;
  1021.         if (y<fg_h)
  1022.           cl=current_level->get_fgline(y)+x1;
  1023.         else cl=NULL;
  1024.         uchar *sl1=draw_y<ncy1 ? 0 : screen->scan_line(draw_y)+xo;
  1025.             
  1026.         for (x=x1,draw_x=xo;x<=x2;x++,draw_x+=xinc,cl++,sl1+=xinc)
  1027.         {
  1028.           if (x<fg_w && y<fg_h)
  1029.           {
  1030.             if (above_tile(*cl))
  1031.               rescan=1;
  1032.             else
  1033.             {
  1034.               int fort_num=fgvalue(*cl);      
  1035.               if (fort_num!=BLACK)
  1036.               {
  1037.                 if (draw_y<ncy1 || draw_y+yinc>=ncy2 || draw_x<ncx1 || draw_x+xinc>=ncx2)
  1038.                   get_fg(fort_num)->im->put_image(screen,draw_x,draw_y);
  1039.                 else
  1040.                   get_fg(fort_num)->im->put_image_offseted(screen,sl1);
  1041.             
  1042.                 if (!(dev & EDIT_MODE))
  1043.                   *cl|=0x8000;      // mark as has-been-seen
  1044.               }    
  1045.             }
  1046.           }
  1047.         }
  1048.       }  
  1049.     }
  1050.     /*        if (dev==0)
  1051.               current_level->put_fg(x,y,ft->next);  */       
  1052.   }
  1053.   
  1054.   DiffTime("      FG",8);//kill me
  1055.  
  1056.   //  if (!(dev&EDIT_MODE))
  1057.   //    server_check();
  1058.  
  1059.   long ro=rand_on;
  1060.   if (dev & DRAW_PEOPLE_LAYER)
  1061.   {
  1062.     if (interpolate)
  1063.       current_level->interpolate_draw_objects(v);
  1064.     else
  1065.       current_level->draw_objects(v);
  1066.   }
  1067.  
  1068.   //  if (!(dev&EDIT_MODE))
  1069.   //    server_check();
  1070.  
  1071.   StartTime(9); //kill me
  1072.   if (!(dev&MAP_MODE))
  1073.   {
  1074.  
  1075.     int fg_h=current_level->foreground_height(),fg_w=current_level->foreground_width();
  1076.  
  1077.     if (dev & DRAW_FG_LAYER && rescan)
  1078.     {
  1079.       for (y=y1,draw_y=yo;y<=y2;y++,draw_y+=yinc)
  1080.       {
  1081.         ushort *cl=current_level->get_fgline(y)+x1;
  1082.         for (x=x1,draw_x=xo;x<=x2;x++,draw_x+=xinc,cl++)
  1083.         {
  1084.           if (above_tile(*cl))
  1085.           {
  1086.             int fort_num=fgvalue(*cl);      
  1087.             if (fort_num!=BLACK)
  1088.             {
  1089.               if (dev & DRAW_BG_LAYER)
  1090.                 get_fg(fort_num)->im->put_image(screen,draw_x,draw_y);
  1091.               else
  1092.                 get_fg(fort_num)->im->put_image_filled(screen,draw_x,draw_y,0);
  1093.             
  1094.               if (!(dev & EDIT_MODE))
  1095.                 current_level->mark_seen(x,y);
  1096.               else
  1097.               {
  1098.                 screen->line(draw_x,draw_y,draw_x+xinc,draw_y+yinc,eh->bright_color());
  1099.                 screen->line(draw_x+xinc,draw_y,draw_x,draw_y+yinc,eh->bright_color());
  1100.               }
  1101.             }    
  1102.           }
  1103.         }
  1104.       }   
  1105.     }
  1106.  
  1107.     
  1108.     if (dev & DRAW_FG_BOUND_LAYER)
  1109.     {
  1110.       int b=eh->bright_color();
  1111.       int fg_h=current_level->foreground_height(),fg_w=current_level->foreground_width();
  1112.  
  1113.       for (y=y1,draw_y=yo;y<=y2;y++,draw_y+=yinc)
  1114.       {
  1115.         ushort *cl;
  1116.         if (y<fg_h)
  1117.           cl=current_level->get_fgline(y)+x1;
  1118.         else cl=NULL;
  1119.         for (x=x1,draw_x=xo;x<=x2;x++,draw_x+=xinc,cl++)
  1120.         {
  1121.           if (x<fg_w && y<fg_h)
  1122.           {
  1123.             int fort_num=fgvalue(*cl);      
  1124.             if (fort_num!=BLACK)
  1125.             {
  1126.               point_list *p=get_fg(fort_num)->points;
  1127.               uchar *d=p->data;    
  1128.               if (p->tot)
  1129.               {
  1130.                 for (int i=1;i<p->tot;i++)
  1131.                 {
  1132.                   d+=2;
  1133.                   screen->line(draw_x+*(d-2),draw_y+*(d-1),draw_x+*d,draw_y+*(d+1),b);
  1134.                 }
  1135.                 screen->line(draw_x+*d,draw_y+*(d-1),draw_x+p->data[0],draw_y+p->data[1],b);
  1136.               }
  1137.             }
  1138.           }
  1139.         }
  1140.       }
  1141.     }
  1142.  
  1143.     //    if (!(dev&EDIT_MODE))
  1144.     //      server_check();
  1145.  
  1146.     if (dev & DRAW_HELP_LAYER)
  1147.     {
  1148.       if (help_text_frames>=0)
  1149.       {
  1150.         int color;
  1151.                 
  1152.         if (help_text_frames<10)
  1153.           color=2;
  1154.         else
  1155.           color=2+(help_text_frames-10);
  1156.                 
  1157.         int x1=v->cx1,y1=v->cy1,x2=v->cx2,y2=v->cy1+eh->font()->height()+10;
  1158.             
  1159.         remap_area(screen,x1,y1,x2,y2,white_light+40*256);
  1160.         screen->bar(x1,y1,x2,y1,color);
  1161.         screen->bar(x1,y2,x2,y2,color);
  1162.             
  1163.         eh->frame_font()->put_string(screen,x1+5,y1+5,
  1164.             help_text,color);
  1165.         if (color>30)
  1166.           help_text_frames=-1;      
  1167.         else help_text_frames++;
  1168.     
  1169.       }    
  1170.     }
  1171.     
  1172.     if (dev_cont)
  1173.       dev_cont->dev_draw(v);  
  1174.     if (cash.in_use())
  1175.       cash.img(vmm_image)->put_image(screen,v->cx1,v->cy2-cash.img(vmm_image)->height()+1);  
  1176.  
  1177.     if (dev&DRAW_LIGHTS)
  1178.     {  
  1179.       if (small_render)
  1180.       {
  1181.         double_light_screen(screen,xoff,yoff,white_light,v->ambient,old_screen,old_cx1,old_cy1);
  1182.             
  1183.         /*        v->cx1=old_cx1;
  1184.         v->cy1=old_cy1;
  1185.         v->cx2=old_cx2;
  1186.         v->cy2=old_cy2; */
  1187.         screen=old_screen;
  1188.       } else
  1189.       {      
  1190.         screen->dirt_on();
  1191.         if (xres*yres<=64000)
  1192.           light_screen(screen,xoff,yoff,white_light,v->ambient);
  1193.         else light_screen(screen,xoff,yoff,white_light,63);            // no lighting for hi-rez
  1194.       }
  1195.  
  1196.     } else 
  1197.       screen->dirt_on();
  1198.  
  1199.  
  1200.  
  1201.   }  else
  1202.     screen->dirt_on();
  1203.  
  1204.   DiffTime("      Other",9); //kill me
  1205.  
  1206.   StartTime(15); // kill me
  1207.   rand_on=ro;                // restore random start in case in draw funs moved it
  1208.   // ... not every machine will draw the same thing
  1209.  
  1210.   post_render();
  1211.  
  1212.   screen->set_clip(cx1,cy1,cx2,cy2);
  1213.     
  1214.  
  1215.  
  1216.  
  1217.   if (playing_state(state))        // draw stuff outside the clipping region
  1218.     v->draw_character_damage();
  1219.  
  1220.   if (profiling())
  1221.     profile_update();
  1222.  
  1223.   sbar.draw_update();
  1224.   DiffTime("      Post",15); //kill me
  1225. }
  1226.  
  1227. void game::put_fg(int x, int y, int type)
  1228.   if (current_level->get_fg(x,y)!=type)
  1229.   {
  1230.     current_level->put_fg(x,y,type);
  1231.     for (view *f=first_view;f;f=f->next)
  1232.       if (f->drawable())
  1233.         draw_map(f);    
  1234.     /*    put_block_bg(x,y,get_bg(current_level->get_bg(x/ASPECT,y/ASPECT))->im);
  1235.           if (type>BLACK)
  1236.           put_block_fg(x,y,get_fg(type)->im); */
  1237.   }
  1238. }
  1239.  
  1240. void game::put_bg(int x, int y, int type)
  1241. {
  1242.   if (current_level->get_bg(x,y)!=type)
  1243.   {
  1244.     current_level->put_bg(x,y,type);
  1245.     for (view *f=first_view;f;f=f->next)
  1246.       if (f->drawable())
  1247.         draw_map(f);    
  1248.     /*    put_block_bg(x,y,get_bg(type)->im);
  1249.           if (current_level->get_fg(x,y)>BLACK) 
  1250.           put_block_fg(x,y,get_fg(current_level->get_fg(x,y))->im);*/
  1251.   }
  1252. }
  1253.  
  1254. int game::in_area(event &ev, int x1, int y1, int x2, int y2)
  1255. {
  1256.   return (last_demo_mx>=x1 && last_demo_mx<=x2 &&
  1257.       last_demo_my>=y1 && last_demo_my<=y2);
  1258. }
  1259.  
  1260. void game::request_level_load(char *name)
  1261. {
  1262.   strcpy(req_name,name);
  1263. }
  1264.  
  1265. extern int start_doubled;
  1266.  
  1267. void fade_in(image *im, int steps)
  1268. {
  1269.   palette *old_pal=pal->copy();
  1270.   int i;
  1271.   if (im)
  1272.   {
  1273.     screen->clear();
  1274.     im->put_image(screen,(xres+1)/2-im->width()/2,(yres+1)/2-im->height()/2);
  1275.   }
  1276.  
  1277.   for (i=0;i<steps;i++)
  1278.   {
  1279.     uchar *sl1=(uchar *)pal->addr();    
  1280.     uchar *sl2=(uchar *)old_pal->addr();    
  1281.     int j;
  1282.     int r,g,b;
  1283.     int v=(i+1)*256/steps;
  1284.     for (j=0;j<256;j++)
  1285.     {
  1286.       *(sl1)=((int)*(sl2))*v/256;  sl1++; sl2++;
  1287.       *(sl1)=((int)*(sl2))*v/256;  sl1++; sl2++;
  1288.       *(sl1)=((int)*(sl2))*v/256;  sl1++; sl2++;
  1289.     }
  1290.     pal->load();
  1291.     eh->flush_screen();
  1292.     milli_wait(25);
  1293.   }
  1294.   delete pal;
  1295.   pal=old_pal;
  1296. }
  1297.  
  1298. void fade_out(int steps)
  1299. {
  1300.   palette *old_pal=pal->copy();
  1301.   int i;
  1302.   for (i=0;i<steps;i++)
  1303.   {
  1304.     uchar *sl1=(uchar *)pal->addr();    
  1305.     uchar *sl2=(uchar *)old_pal->addr();    
  1306.     int j;
  1307.     int r,g,b;
  1308.     int v=(steps-i)*256/steps;
  1309.     for (j=0;j<256;j++)
  1310.     {
  1311.       *(sl1)=((int)*(sl2))*v/256;  sl1++; sl2++;
  1312.       *(sl1)=((int)*(sl2))*v/256;  sl1++; sl2++;
  1313.       *(sl1)=((int)*(sl2))*v/256;  sl1++; sl2++;
  1314.     }
  1315.     pal->load();
  1316.     eh->flush_screen();
  1317.     milli_wait(25);
  1318.   }
  1319.   screen->clear();
  1320.   eh->flush_screen();
  1321.   delete pal;
  1322.   pal=old_pal;
  1323.   
  1324.   pal->load();
  1325. }
  1326.  
  1327. int text_draw(int y, int x1, int y1, int x2, int y2, char *buf, JCFont *font, uchar *cmap, char color);
  1328.  
  1329. void do_title()
  1330. {
  1331.   if (cdc_logo!=-1)
  1332.   {
  1333.     if (sound_avail&MUSIC_INITIALIZED)
  1334.     {
  1335.       if (current_song) { current_song->stop(); delete current_song; }
  1336.       current_song=new song("music/intro.hmi");
  1337.       current_song->play(music_volume);
  1338.     }
  1339.  
  1340.     void *logo_snd=symbol_value(make_find_symbol("LOGO_SND"));
  1341.  
  1342.     if (DEFINEDP(logo_snd) && (sound_avail&SFX_INITIALIZED))
  1343.       cash.sfx(lnumber_value(logo_snd))->play(sfx_volume);
  1344.  
  1345.     image blank(2,2); blank.clear();
  1346.     eh->set_mouse_shape(blank.copy(),0,0);      // don't show mouse
  1347.     fade_in(cash.img(cdc_logo),32);
  1348.     
  1349.     milli_wait(900);
  1350.  
  1351.     void *space_snd=symbol_value(make_find_symbol("SPACE_SND"));
  1352.  
  1353.     fade_out(32);
  1354.     milli_wait(300);
  1355.  
  1356.     int i,abort=0;
  1357.     char *str=lstring_value(eval(make_find_symbol("plot_start")));
  1358.     
  1359.     bFILE *fp=open_file("art/smoke.spe","rb");
  1360.     if (!fp->open_failure())
  1361.     {
  1362.       spec_directory sd(fp);
  1363.       palette *old_pal=pal;
  1364.       pal=new palette(sd.find(SPEC_PALETTE),fp);
  1365.       pal->shift(1);
  1366.  
  1367.       image *gray=new image(sd.find("gray_pict"),fp);
  1368.       image *smoke[5];
  1369.  
  1370.       char nm[20];
  1371.       for (i=0;i<5;i++)
  1372.       {
  1373.         sprintf(nm,"smoke%04d.pcx",i+1);
  1374.         smoke[i]=new image(sd.find(nm),fp);
  1375.       }
  1376.  
  1377.       screen->clear();
  1378.       pal->load();
  1379.  
  1380.       int dx=(xres+1)/2-gray->width()/2,dy=(yres+1)/2-gray->height()/2;
  1381.       gray->put_image(screen,dx,dy);
  1382.       smoke[0]->put_image(screen,dx+24,dy+5);
  1383.  
  1384.       fade_in(NULL,16);
  1385.       uchar cmap[32];
  1386.       for (i=0;i<32;i++)
  1387.         cmap[i]=pal->find_closest(i*256/32,i*256/32,i*256/32);
  1388.  
  1389.       event ev; ev.type=EV_SPURIOUS;
  1390.       time_marker start;
  1391.  
  1392.  
  1393.       for (i=0;i<600 && ev.type!=EV_KEY && ev.type!=EV_MOUSE_BUTTON;i++)
  1394.       {
  1395.         gray->put_part(screen,dx,dy,0,0,319,199);
  1396.         smoke[i%5]->put_image(screen,dx+65,dy+70);
  1397.         text_draw(205-i,dx+15,dy,dx+320-15,dy+199,str,eh->font(),cmap,eh->bright_color());
  1398.         eh->flush_screen();
  1399.         time_marker now;
  1400.         while (now.diff_time(&start)<0.15) 
  1401.           now.get_time();
  1402.         start.get_time();
  1403.             
  1404.         while (eh->event_waiting() && ev.type!=EV_KEY) eh->get_event(ev);
  1405.         if ((i%5)==0 && DEFINEDP(space_snd) && (sound_avail&SFX_INITIALIZED))
  1406.           cash.sfx(lnumber_value(space_snd))->play(sfx_volume*90/127);
  1407.       }
  1408.  
  1409.       the_game->reset_keymap();
  1410.  
  1411.       fade_out(16);
  1412.  
  1413.       for (i=0;i<5;i++) delete smoke[i];
  1414.       delete gray;
  1415.  
  1416.       delete pal;
  1417.       pal=old_pal;
  1418.     }
  1419.     delete fp;
  1420.  
  1421.     for (i=0;i<100 && !abort;i++)
  1422.     {
  1423.       
  1424.     }
  1425.  
  1426.  
  1427.  
  1428.     if (title_screen>=0)
  1429.       fade_in(cash.img(title_screen),32);
  1430.  
  1431.     eh->set_mouse_shape(cash.img(c_normal)->copy(),1,1);
  1432.   }
  1433. }
  1434.  
  1435. extern int start_edit;
  1436.  
  1437. void game::request_end()
  1438. {
  1439.   req_end=1;
  1440. }
  1441.  
  1442. extern void fast_load_start_recording(char *name);
  1443. extern void fast_load_stop_recording();
  1444. extern void fast_load_start_reloading(char *name);
  1445. extern void fast_load_stop_reloading();
  1446.  
  1447. game::game(int argc, char **argv)
  1448. {
  1449.   int i;
  1450.   req_name[0]=0;
  1451.   bg_xmul=bg_ymul=1;
  1452.   bg_xdiv=bg_ydiv=8;
  1453.   last_input=NULL;
  1454.   current_level=NULL;
  1455.   refresh=1;  
  1456.   the_game=this;  
  1457.   top_menu=joy_win=NULL;
  1458.   old_view=first_view=NULL;
  1459.   nplayers=1;
  1460.  
  1461.   help_text_frames=0;  
  1462.   strcpy(help_text,"");
  1463.  
  1464.   for (i=1;i<argc;i++)
  1465.     if (!strcmp(argv[i],"-no_delay"))
  1466.     {
  1467.       no_delay=1;
  1468.       dprintf("Frame delay off (-nodelay)\n");
  1469.     }
  1470.   
  1471.   image_init();  
  1472.   zoom=15;  
  1473.   no_delay=0;
  1474.  
  1475.   if (get_option("-use_joy"))  
  1476.   {
  1477.     has_joystick=joy_init(argc,argv);
  1478.     dprintf("Joystick : ");
  1479.     if (has_joystick) dprintf("detected\n");
  1480.     else dprintf("not detected\n");
  1481.   }
  1482.   else has_joystick=0;
  1483.  
  1484.   //    fast_load_start_recording("fastload.dat");
  1485.   load_data(argc,argv);  
  1486.   //    fast_load_stop_recording();
  1487.  
  1488.   get_key_bindings();
  1489.  
  1490.  
  1491.   reset_keymap();                   // we think all the keys are up right now
  1492.   finished=0;
  1493.  
  1494.   calc_light_table(pal);
  1495.  
  1496.   if (current_level==NULL && net_start())  // if we joined a net game get level from server
  1497.   {
  1498.     if (!request_server_entry())
  1499.     {
  1500.       exit(0);
  1501.     }
  1502.     net_reload();
  1503.     //    load_level(NET_STARTFILE); 
  1504.   }
  1505.  
  1506.  
  1507.   if (get_option("-2") && (xres<639 || yres<399))
  1508.   {
  1509.     close_graphics();
  1510.     dprintf("Resolution must be > 640x400 to use -2 option\n");    
  1511.     exit(0);
  1512.   }
  1513.   pal->load();
  1514.   
  1515.   recalc_local_view_space();   // now that we know what size the screen is...
  1516.  
  1517.   dark_color=get_color(cash.img(window_colors)->pixel(2,0));
  1518.   bright_color=get_color(cash.img(window_colors)->pixel(0,0));
  1519.   med_color=get_color(cash.img(window_colors)->pixel(1,0));
  1520.  
  1521.   morph_dark_color=get_color(cash.img(window_colors)->pixel(2,1));
  1522.   morph_bright_color=get_color(cash.img(window_colors)->pixel(0,1));
  1523.   morph_med_color=get_color(cash.img(window_colors)->pixel(1,1));
  1524.   morph_sel_frame_color=pal->find_closest(255,255,0);
  1525.   light_connection_color=morph_sel_frame_color;
  1526.  
  1527.   if (NILP(symbol_value(l_default_font)))
  1528.   {
  1529.     dprintf("No font defined, set symbol default-font to an image name\n");
  1530.     exit(0);
  1531.   }
  1532.  
  1533.   int font_pict=big_font_pict;
  1534.   
  1535.   if (console_font_pict==-1) console_font_pict=font_pict;
  1536.   game_font=new JCFont(cash.img(big_font_pict));
  1537.   window_font=new JCFont(cash.img(small_font_pict));
  1538.  
  1539.   console_font=new JCFont(cash.img(console_font_pict));
  1540.  
  1541.   eh=new window_manager(screen,pal,bright_color,
  1542.       med_color,
  1543.       dark_color,
  1544.       game_font);  
  1545.   idle_man=new idle_manager;
  1546.  
  1547.  
  1548.   eh->set_frame_font(window_font);
  1549.  
  1550.   chat=new chat_console(eh,console_font,50,6);
  1551.  
  1552.   if (!eh->has_mouse())
  1553.   {
  1554.     close_graphics();
  1555.     image_uninit();
  1556.     dprintf("No mouse driver detected, please rectify.\n");
  1557.     exit(0);
  1558.   }
  1559.  
  1560.   gamma_correct(pal);
  1561.  
  1562.   if (main_net_cfg==NULL || (main_net_cfg->state!=net_configuration::SERVER &&
  1563.       main_net_cfg->state!=net_configuration::CLIENT))
  1564.   {
  1565.     if (!start_edit && !net_start())
  1566.       do_title();
  1567.   } else if (main_net_cfg && main_net_cfg->state==net_configuration::SERVER)
  1568.   {
  1569.     the_game->load_level(level_file);
  1570.     start_running=1;
  1571.   }
  1572.     
  1573.   dev|= DRAW_FG_LAYER | DRAW_BG_LAYER | DRAW_PEOPLE_LAYER | DRAW_HELP_LAYER | DRAW_LIGHTS | DRAW_LINKS;
  1574.  
  1575.   if (dev & EDIT_MODE)
  1576.     set_frame_size(0);
  1577.   //  do_intro();
  1578.   state=START_STATE;         // first set the state to one that has windows
  1579.  
  1580.   if (start_running)
  1581.     set_state(RUN_STATE);
  1582.   else
  1583.   {
  1584.     screen->clear();  
  1585.     if (title_screen>=0)
  1586.     {
  1587.       image *tit=cash.img(title_screen);
  1588.       tit->put_image(screen,screen->width()/2-tit->width()/2,
  1589.           screen->height()/2-tit->height()/2);
  1590.     }   
  1591.     set_state(MENU_STATE);   // then go to menu state so windows will turn off
  1592.   }
  1593. }
  1594.  
  1595.  
  1596.  
  1597. time_marker *led_last_time=NULL,*fps_mark_start=NULL;
  1598. double avg_fps=15.0,possible_fps=15.0;
  1599.  
  1600. void game::toggle_delay()
  1601. {
  1602.   no_delay=!no_delay;
  1603.   if (no_delay)
  1604.     show_help(symbol_str("delay_off"));
  1605.   else show_help(symbol_str("delay_on"));
  1606.   avg_fps=possible_fps=15.0;
  1607. }
  1608.  
  1609. void game::show_time()
  1610. {
  1611.   if (first_view && fps_on)
  1612.   {
  1613.     char str[10];
  1614.     sprintf(str,"%d",(long)(avg_fps*10.0));
  1615.     console_font->put_string(screen,first_view->cx1,first_view->cy1,str);
  1616.  
  1617.     sprintf(str,"%d",total_active);
  1618.     console_font->put_string(screen,first_view->cx1,first_view->cy1+10,str);
  1619.   }
  1620.  
  1621. #ifdef MAC_PROFILE
  1622.   for (int i=0; i<KJCOUNTERS; i++)
  1623.     console_font->put_string(screen,10,8*i+8,kjfie[i]); // kill me
  1624. #endif
  1625. }
  1626.  
  1627. void game::update_screen()
  1628. {
  1629.   if (state==HELP_STATE)
  1630.     draw_help();
  1631.   else if (current_level)
  1632.   {    
  1633.     if (!(dev & EDIT_MODE) || refresh)    
  1634.     {    
  1635.       view *f=first_view;
  1636.       current_level->clear_active_list();
  1637.       for (;f;f=f->next)
  1638.       {
  1639.         if (f->focus)           
  1640.         {
  1641.           int w,h;
  1642.             
  1643.           w=(f->cx2-f->cx1+1);
  1644.           h=(f->cy2-f->cy1+1);
  1645.             
  1646.           total_active+=current_level->add_drawables(f->xoff()-w/4,f->yoff()-h/4,
  1647.               f->xoff()+w+w/4,f->yoff()+h+h/4);
  1648.             
  1649.         }
  1650.       }
  1651.  
  1652.       for (f=first_view;f;f=f->next)
  1653.       {
  1654.         if (f->drawable())
  1655.         {
  1656.           StartTime(5); // kill me
  1657.           if (interpolate_draw)
  1658.           {
  1659.             draw_map(f,1);
  1660.             eh->flush_screen();
  1661.           }
  1662.           draw_map(f,0);
  1663.           DiffTime("    Drawmap",5); // kill me
  1664.         }
  1665.       }
  1666.  
  1667.     }  
  1668.     if (state==PAUSE_STATE)
  1669.     {
  1670.       for (view *f=first_view;f;f=f->next)
  1671.         cash.img(pause_image)->put_image(screen,(f->cx1+f->cx2)/2-cash.img(pause_image)->width()/2,
  1672.             f->cy1+5,1);
  1673.     }
  1674.     
  1675.     show_time();
  1676.   }
  1677.  
  1678.   if (state==RUN_STATE && cash.prof_is_on())
  1679.     cash.prof_poll_end();
  1680.  
  1681.   StartTime(16); //kill me
  1682.   eh->flush_screen();
  1683.   DiffTime("    Flush",16); //kill me
  1684. }
  1685.  
  1686. void game::do_intro()
  1687. {
  1688.  
  1689. }
  1690.  
  1691. #if 1
  1692. int game::calc_speed()
  1693. {
  1694.   int ret=0;
  1695.   if (fps_mark_start)
  1696.   {
  1697.  
  1698.     time_marker t;
  1699.  
  1700.     // find average fps for last 10 frames
  1701.     double td=t.diff_time(fps_mark_start);
  1702.     if (td<0.001)     // something is rotten in the state of demark
  1703.       td=0.001;
  1704.  
  1705.     avg_fps=avg_fps*9.0/10.0+1.0/(td*10.0);  
  1706.     possible_fps=possible_fps*9.0/10.0+1.0/(td*10.0);  
  1707.  
  1708.     if (avg_fps>14)
  1709.     {
  1710.       if (massive_frame_panic>20)
  1711.         massive_frame_panic=20;
  1712.       else if (massive_frame_panic)
  1713.         massive_frame_panic--;
  1714.     }
  1715.  
  1716.     if (avg_fps>15 && ((dev&EDIT_MODE)==0 || need_delay))
  1717.     {
  1718.       frame_panic=0;
  1719.       long stime=(long)((1/15.0-1.0/possible_fps)*1000.0); 
  1720.       if (stime>0 && !no_delay)
  1721.       {
  1722.         milli_wait(stime);
  1723.         avg_fps-=1.0/(td*10.0);        // subtract out old estimate
  1724.             
  1725.         time_marker t;
  1726.                 
  1727.         // find average fps for last 10 frames
  1728.         double td=t.diff_time(fps_mark_start);
  1729.         if (td<0.00001)     // something is rotten in the state of demark
  1730.           td=0.00001;
  1731.             
  1732.         avg_fps+=1.0/(td*10.0);       // add in new estimate
  1733.       }
  1734.     } else if (avg_fps<14)
  1735.     {
  1736.       if (avg_fps<10)
  1737.         massive_frame_panic++;
  1738.       frame_panic++;
  1739.       ret=1;
  1740.     }
  1741.     
  1742.     delete fps_mark_start;    
  1743.   }
  1744.   fps_mark_start=new time_marker;
  1745.   return ret;
  1746. }
  1747. #else
  1748. int game::calc_speed()
  1749. {
  1750.   static UnsignedWide last_t = {0,0};
  1751.   UnsignedWide t;
  1752.     
  1753.   if (dev & EDIT_MODE)
  1754.     return 0;
  1755.     
  1756.   do 
  1757.   {
  1758.     Microseconds(&t);
  1759.   } while( t.lo - last_t.lo < 60000);
  1760.     
  1761.   last_t = t;
  1762.     
  1763.   return 0;
  1764. }
  1765. #endif
  1766.  
  1767. extern int start_edit;
  1768.  
  1769. void single_render();
  1770. void double_render();
  1771.  
  1772. void game::get_input()
  1773. {
  1774.   event ev;  
  1775.   idle_ticks++;
  1776.   while (event_waiting(eh))
  1777.   {
  1778.     get_event(ev,eh);
  1779.  
  1780.     if (ev.type==EV_MOUSE_MOVE) last_input=ev.window;
  1781.     // don't process repeated keys in the main window, it will slow down the game handle such
  1782.     // useless events. However in other windows it might be useful, such as in input windows
  1783.     // where you want to repeatedly scroll down..
  1784.     if (ev.type!=EV_KEY || !key_down(ev.key) || ev.window || (dev&EDIT_MODE))
  1785.     {
  1786.       if (ev.type==EV_KEY)     
  1787.       {
  1788.         set_key_down(ev.key,1);
  1789.         if (playing_state(state))
  1790.         {     
  1791.           if (ev.key<256)
  1792.           {
  1793.             if (chat && chat->chat_event(ev))
  1794.               base->packet.write_byte(SCMD_CHAT_KEYPRESS);
  1795.             else
  1796.               base->packet.write_byte(SCMD_KEYPRESS);
  1797.           }
  1798.           else
  1799.             base->packet.write_byte(SCMD_EXT_KEYPRESS);
  1800.           base->packet.write_byte(client_number());
  1801.           if (ev.key>256)
  1802.             base->packet.write_byte(ev.key-256);
  1803.           else
  1804.             base->packet.write_byte(ev.key);      
  1805.         }
  1806.       }
  1807.       else if (ev.type==EV_KEYRELEASE)
  1808.       {
  1809.         set_key_down(ev.key,0);
  1810.         if (playing_state(state))
  1811.         {     
  1812.           if (ev.key<256)
  1813.             base->packet.write_byte(SCMD_KEYRELEASE);
  1814.           else
  1815.             base->packet.write_byte(SCMD_EXT_KEYRELEASE);
  1816.           base->packet.write_byte(client_number());
  1817.           if (ev.key>255)
  1818.             base->packet.write_byte(ev.key-256);
  1819.           else
  1820.             base->packet.write_byte(ev.key);      
  1821.         }    
  1822.       }
  1823.       
  1824.       if ((dev&EDIT_MODE) || start_edit || ev.type==EV_MESSAGE)
  1825.         dev_cont->handle_event(ev);
  1826.  
  1827.       view *v=first_view;
  1828.       for (;v;v=v->next)
  1829.         if (v->local_player() && v->handle_event(ev))
  1830.           ev.type=EV_SPURIOUS;       // if the event was used by the view, gobble it up
  1831.  
  1832.  
  1833.       
  1834.       help_handle_event(ev);    
  1835.       mousex=last_demo_mx;
  1836.       mousey=last_demo_my;
  1837.  
  1838.       if (ev.type==EV_MESSAGE)
  1839.       {
  1840.         switch (ev.message.id)
  1841.         {
  1842.           case CALB_JOY : 
  1843.           { 
  1844.             if (!joy_win)
  1845.             {
  1846.               int wx=WINDOW_FRAME_LEFT,wy=WINDOW_FRAME_TOP;
  1847.                       
  1848.               joy_win=eh->new_window(80,50,-1,-1,
  1849.                   new button(wx+70,wy+9,JOY_OK,"OK",
  1850.                       new info_field(wx,wy+30,DEV_NULL,
  1851.                           " Center joystick and\n"
  1852.                           "press the fire button",NULL)),
  1853.             
  1854.                   "Joystick");
  1855.               set_state(JOY_CALB_STATE); 
  1856.             }
  1857.           }
  1858.           case TOP_MENU :
  1859.           { menu_select(ev); } break;
  1860.           case DEV_QUIT :
  1861.           { finished=1; } break;
  1862.             
  1863.         }
  1864.       }        
  1865.       else if (ev.type==EV_CLOSE_WINDOW && ev.window==top_menu)
  1866.       {
  1867.         eh->close_window(top_menu);
  1868.         top_menu=NULL;
  1869.       }
  1870.     
  1871.       switch (state)
  1872.       {
  1873.         case JOY_CALB_STATE :
  1874.         { joy_calb(ev); } break;
  1875.         case INTRO_START_STATE : 
  1876.         { do_intro(); 
  1877.         if (dev & EDIT_MODE)
  1878.           set_state(RUN_STATE);
  1879.         else
  1880.           set_state(MENU_STATE); 
  1881.         } break;     
  1882.         case PAUSE_STATE : if (ev.type==EV_KEY && (ev.key==JK_SPACE || ev.key==JK_ENTER)) 
  1883.         { set_state(RUN_STATE); } break;
  1884.         case RUN_STATE : 
  1885.         {
  1886.           if (ev.window==NULL)
  1887.           {
  1888.                   
  1889.             switch (ev.type)
  1890.             {
  1891.               case EV_KEY : 
  1892.               { switch (ev.key)
  1893.               {
  1894.                 case 'm' : 
  1895.                 { 
  1896.                   if (dev&MAP_MODE) dev-=MAP_MODE;
  1897.                   else if ((player_list && player_list->next) || dev&EDIT_MODE) dev|=MAP_MODE;
  1898.                 
  1899.                   if (!(dev&MAP_MODE))
  1900.                   {
  1901.                     if (dev_cont->tbw) dev_cont->toggle_toolbar();
  1902.                     edit_mode=ID_DMODE_DRAW;
  1903.                   }
  1904.                   need_refresh();     
  1905.                 } break;
  1906.                 case 'v' : 
  1907.                 { eh->push_event(new event(DO_VOLUME,NULL)); } break;
  1908.                 case 'p' : 
  1909.                 { if (!(dev&EDIT_MODE) && (!main_net_cfg || 
  1910.                     (main_net_cfg->state!=net_configuration::SERVER &&
  1911.                         main_net_cfg->state!=net_configuration::CLIENT)))  
  1912.                   set_state(PAUSE_STATE); 
  1913.                 } break;
  1914.                 case 'S' : 
  1915.                   if (start_edit)
  1916.                   { eh->push_event(new event(ID_LEVEL_SAVE,NULL)); } break;
  1917.                 case JK_TAB : 
  1918.                 { if (start_edit) toggle_edit_mode(); need_refresh(); } break;
  1919.                 case 'c' :          
  1920.                 { if (chatting_enabled && (!(dev&EDIT_MODE) && chat))
  1921.                   chat->toggle();
  1922.                 } break;
  1923.                 case '9' : 
  1924.                 { dev=dev^PERFORMANCE_TEST_MODE; need_refresh(); } break;
  1925.                 
  1926.                 /*
  1927.                   case '=' :
  1928.                   case '+' : 
  1929.                   { if (!dev_cont->need_plus_minus())
  1930.                   { 
  1931.                   if (eh->key_pressed(JK_CTRL_L))
  1932.                   grow_views(20);
  1933.                   else
  1934.                   grow_views(5); 
  1935.                   draw(state==SCENE_STATE);
  1936.                   }
  1937.                   } break;
  1938.                   case JK_F10 : make_screen_size(311,160); break;
  1939.                   case '_' :
  1940.                   case '-' : 
  1941.                   {
  1942.                   if (!dev_cont->need_plus_minus())            
  1943.                   { 
  1944.                   if (eh->key_pressed(JK_CTRL_L))
  1945.                   grow_views(-20);
  1946.                   else
  1947.                   grow_views(-5); 
  1948.                   draw(state==SCENE_STATE); 
  1949.                   } 
  1950.                   } break; */
  1951.                 
  1952.               }
  1953.             } break;            
  1954.               case EV_RESIZE : 
  1955.               { 
  1956.                 view *v;
  1957.                 for (v=first_view;v;v=v->next)  // see if any views need to change size
  1958.                 {
  1959.                   if (v->local_player())
  1960.                   {
  1961.                     int w=(xres-10)/(small_render ? 2 : 1);
  1962.                     int h=(yres-10)/(small_render ? 2 : 1);
  1963.                 
  1964.                     /*                    v->suggest.send_view=1;
  1965.                     v->suggest.cx1=5;
  1966.                     v->suggest.cx2=5+w;
  1967.                     v->suggest.cy1=5;
  1968.                     v->suggest.cy2=5+h;
  1969.                     v->suggest.pan_x=v->pan_x;
  1970.                     v->suggest.pan_y=v->pan_y;
  1971.                     v->suggest.shift_down=v->shift_down;
  1972.                     v->suggest.shift_right=v->shift_right; */
  1973.                   }          
  1974.                 }
  1975.                 draw(); 
  1976.               } break;
  1977.               case EV_REDRAW : 
  1978.                 screen->add_dirty(ev.redraw.x1,ev.redraw.y1,
  1979.                     ev.redraw.x2,ev.redraw.y2); 
  1980.                 break;
  1981.               case EV_MESSAGE :        
  1982.                 switch (ev.message.id)
  1983.                 {
  1984.                   case RAISE_SFX :
  1985.                   case LOWER_SFX :
  1986.                   case RAISE_MUSIC :
  1987.                   case LOWER_MUSIC :
  1988.                     if (ev.message.id==RAISE_SFX && sfx_volume!=127) sfx_volume=min(127,sfx_volume+16);
  1989.                     if (ev.message.id==LOWER_SFX && sfx_volume!=0) sfx_volume=max(sfx_volume-16,0);
  1990.                     if (ev.message.id==RAISE_MUSIC && music_volume!=126) 
  1991.                     {            
  1992.                       music_volume=min(music_volume+16,127);
  1993.                       if (current_song && (sound_avail&MUSIC_INITIALIZED))
  1994.                         current_song->set_volume(music_volume);
  1995.                     }
  1996.               
  1997.                     if (ev.message.id==LOWER_MUSIC && music_volume!=0) 
  1998.                     {            
  1999.                       music_volume=max(music_volume-16,0);
  2000.                       if (current_song && (sound_avail&MUSIC_INITIALIZED))
  2001.                         current_song->set_volume(music_volume);
  2002.                     }            
  2003.               
  2004.                     ((button *)ev.message.data)->push();          
  2005.                     break;
  2006.                 }
  2007.                       
  2008.             }
  2009.           }
  2010.           } break;
  2011.       }
  2012.     }
  2013.   }
  2014. }
  2015.  
  2016.  
  2017. void net_send(int force=0)
  2018. {
  2019.   if ( (!(dev&EDIT_MODE)) || force)
  2020.   {
  2021.     if (demo_man.state==demo_manager::PLAYING)
  2022.     {
  2023.       base->input_state=INPUT_PROCESSING;
  2024.     } else
  2025.     {
  2026.       
  2027.  
  2028.  
  2029.       if (!player_list->focus)
  2030.       {
  2031.         dprintf("Players have not been created\ncall create_players");
  2032.         exit(0);
  2033.       }
  2034.  
  2035.  
  2036.       view *p=player_list;
  2037.       for (;p;p=p->next)
  2038.         if (p->local_player())
  2039.           p->get_input();
  2040.  
  2041.  
  2042.       base->packet.write_byte(SCMD_SYNC);
  2043.       base->packet.write_short(make_sync());
  2044.  
  2045.       if (base->join_list)
  2046.         base->packet.write_byte(SCMD_RELOAD);
  2047.  
  2048.       //      dprintf("save tick %d, pk size=%d, rand_on=%d, sync=%d\n",current_level->tick_counter(),
  2049.       //         base->packet.packet_size(),rand_on,make_sync());
  2050.       send_local_request();
  2051.     }
  2052.   }
  2053. }
  2054.  
  2055. void net_receive()
  2056. {
  2057.   if (!(dev&EDIT_MODE) && current_level)
  2058.   {
  2059.     uchar buf[PACKET_MAX_SIZE+1];
  2060.     int size;
  2061.  
  2062.     if (demo_man.state==demo_manager::PLAYING)
  2063.     { 
  2064.       if (!demo_man.get_packet(buf,size))
  2065.         size=0;
  2066.       base->packet.packet_reset();
  2067.       base->mem_lock=0;
  2068.     } else
  2069.     {
  2070.       size=get_inputs_from_server(buf);
  2071.       if (demo_man.state==demo_manager::RECORDING)
  2072.         demo_man.save_packet(buf,size);
  2073.     }
  2074.  
  2075.     process_packet_commands(buf,size);
  2076.   }
  2077. }
  2078.  
  2079. void game::step()
  2080. {
  2081.   clear_tmp();
  2082.   if (current_level)
  2083.   {
  2084.     current_level->unactivate_all();
  2085.     total_active=0;
  2086.     for (view *f=first_view;f;f=f->next)
  2087.     {
  2088.       if (f->focus)           
  2089.       {
  2090.         f->update_scroll();
  2091.         int w,h;
  2092.             
  2093.         w=(f->cx2-f->cx1+1);
  2094.         h=(f->cy2-f->cy1+1);
  2095.         total_active+=current_level->add_actives(f->xoff()-w/4,f->yoff()-h/4,
  2096.             f->xoff()+w+w/4,f->yoff()+h+h/4);
  2097.       }
  2098.     }
  2099.   }
  2100.  
  2101.   if (state==RUN_STATE)
  2102.   {    
  2103.     if ((dev&EDIT_MODE) || (main_net_cfg && (main_net_cfg->state==net_configuration::CLIENT ||
  2104.         main_net_cfg->state==net_configuration::SERVER)))
  2105.       idle_ticks=0;
  2106.  
  2107.     if (demo_man.current_state()==demo_manager::NORMAL && idle_ticks>420 && demo_start)
  2108.     {
  2109.       idle_ticks=0;
  2110.       set_state(MENU_STATE);    
  2111.     }
  2112.     else if (!(dev & EDIT_MODE))               // if edit mode, then don't step anything
  2113.     {
  2114. #ifdef __MAC__
  2115.       if (key_down(JK_ESC) || (key_down('q') && key_down(JK_COMMAND)))
  2116. #else
  2117.         if (key_down(JK_ESC))
  2118. #endif
  2119.         {
  2120.           set_state(MENU_STATE);
  2121.           set_key_down(JK_ESC,0);
  2122.           return;
  2123.         }
  2124.       ambient_ramp=0;
  2125.       view *v;
  2126.       for (v=first_view;v;v=v->next)
  2127.         v->update_scroll();
  2128.  
  2129.       cash.prof_poll_start();
  2130.       current_level->tick();
  2131.       sbar.step();
  2132.     } else    
  2133.       dev_scroll();  
  2134.   } else if (state==JOY_CALB_STATE)
  2135.   {
  2136.     event ev;
  2137.     joy_calb(ev);
  2138.   } else if (state==MENU_STATE)  
  2139.     main_menu();  
  2140.     
  2141.   if (key_down('x') && (key_down(JK_ALT_L) || key_down(JK_ALT_R)) && confirm_quit()) finished=1;
  2142. }
  2143.  
  2144. extern void *current_demo;
  2145.  
  2146. game::~game()
  2147. {  
  2148.   delete idle_man;
  2149.   idle_man=0;
  2150.  
  2151.   current_demo=NULL;
  2152.   if (first_view==player_list) first_view=NULL;
  2153.   while (player_list)
  2154.   {
  2155.     view *p=player_list;
  2156.     game_object *o=p->focus;
  2157.     player_list=player_list->next;
  2158.     delete p;
  2159.     o->set_controller(NULL);
  2160.     if (current_level && o)
  2161.       current_level->delete_object(o);
  2162.     else delete o;
  2163.   }
  2164.  
  2165.   if (current_level) { delete current_level; current_level=NULL; }
  2166.  
  2167.   if (first_view!=player_list)
  2168.   {
  2169.     while (player_list)
  2170.     {
  2171.       view *p=player_list;
  2172.       player_list=player_list->next;
  2173.       delete p;
  2174.     }
  2175.   }
  2176.  
  2177.   while (first_view)
  2178.   {
  2179.     view *p=first_view;
  2180.     first_view=first_view->next;
  2181.     delete p;
  2182.   }
  2183.  
  2184.   player_list=NULL;  
  2185.  
  2186.   if (old_view)
  2187.   {
  2188.     first_view=old_view;
  2189.     while (first_view)
  2190.     {
  2191.       view *p=first_view;
  2192.       first_view=first_view->next;
  2193.       delete p;
  2194.     }
  2195.   }
  2196.   old_view=NULL;
  2197.  
  2198.   int i=0;
  2199.   for (;i<total_objects;i++)
  2200.   {
  2201.     jfree(object_names[i]);
  2202.     delete figures[i];
  2203.   }
  2204.   if (fps_mark_start) delete fps_mark_start; fps_mark_start=NULL;
  2205.   delete pal;
  2206.   jfree(object_names);
  2207.   jfree(figures);
  2208.  
  2209.   jfree(backtiles);
  2210.   jfree(foretiles);
  2211.   if (total_weapons)
  2212.     jfree(weapon_types);
  2213.  
  2214.   config_cleanup();
  2215.   delete color_table;
  2216.   delete eh;
  2217.   delete game_font;
  2218.   delete window_font;
  2219.   delete big_font;
  2220.   delete console_font;
  2221.   if (total_help_screens)
  2222.     jfree(help_screens);
  2223.     
  2224.  
  2225.   //  image_uninit();
  2226. }
  2227.  
  2228.  
  2229.  
  2230. void game::draw(int scene_mode)
  2231. {
  2232.   screen->add_dirty(0,0,xres,yres);
  2233.   image *bt=cash.img(border_tile);
  2234.   int tw=bt->width(),th=bt->height(),dx,dy=0;
  2235.   int xt=screen->width()/tw+1,yt=screen->height()/th+1,x,y;
  2236.   screen->clear();
  2237.   //  for (y=0;y<yt;y++,dy+=th)
  2238.   //    for (x=0,dx=0;x<xt;x++,dx+=tw)
  2239.   //      bt->put_image(screen,dx,dy); 
  2240.   int lr=eh->bright_color(),
  2241.     mr=eh->medium_color();
  2242.  
  2243.   if (scene_mode)
  2244.   {
  2245.     char *helpstr="ARROW KEYS CHANGE TEXT SPEED";
  2246.     eh->font()->put_string(screen,screen->width()/2-(eh->font()->width()*strlen(helpstr))/2+1,
  2247.         screen->height()-eh->font()->height()-5+1,helpstr,eh->dark_color());    
  2248.     eh->font()->put_string(screen,screen->width()/2-(eh->font()->width()*strlen(helpstr))/2,
  2249.         screen->height()-eh->font()->height()-5,helpstr,eh->bright_color());    
  2250.   }
  2251.   /*  else
  2252.       {
  2253.       char *helpstr="PRESS h FOR HELP";
  2254.       eh->font()->put_string(screen,screen->width()-eh->font()->width()*strlen(helpstr)-5,
  2255.       screen->height()-eh->font()->height()-5,helpstr);
  2256.       }*/
  2257.   /*  int dc=cash.img(window_colors)->pixel(0,2);
  2258.       int mc=cash.img(window_colors)->pixel(1,2);
  2259.       int bc=cash.img(window_colors)->pixel(2,2);
  2260.       screen->line(0,0,screen->width()-1,0,dc);
  2261.       screen->line(0,0,0,screen->height()-1,dc);
  2262.       screen->line(0,screen->height()-1,screen->width()-1,screen->height()-1,bc);
  2263.       screen->line(screen->width()-1,0,screen->width()-1,screen->height()-1,bc);*/
  2264.   for (view *f=first_view;f;f=f->next)
  2265.     draw_map(f,0);
  2266.  
  2267.   sbar.redraw(screen);
  2268. }
  2269.  
  2270. int external_print=0;
  2271.  
  2272. void start_sound(int argc, char **argv)
  2273. {
  2274.   sfx_volume=music_volume=127;
  2275.  
  2276.   for (int i=1;i<argc;i++)
  2277.     if (!strcmp(argv[i],"-sfx_volume"))
  2278.     {
  2279.       i++;
  2280.       if (atoi(argv[i])>=0 && atoi(argv[i])<127)
  2281.         sfx_volume=atoi(argv[i]);
  2282.       else dprintf("Bad sound effects volume level, use 0..127\n");      
  2283.     }
  2284.     else if (!strcmp(argv[i],"-music_volume"))
  2285.     {
  2286.       i++;
  2287.       if (atoi(argv[i])>=0 && atoi(argv[i])<127)
  2288.         music_volume=atoi(argv[i]);
  2289.       else dprintf("Bad music volume level, use 0..127\n");      
  2290.     }
  2291.  
  2292.   sound_avail=sound_init(argc,argv);
  2293. }
  2294.  
  2295. void game_printer(char *st)
  2296. {
  2297.  
  2298. #if 1
  2299.     static FILE *f = 0;
  2300.     if (!f)
  2301.         f = fopen("abuse.out","wt");
  2302.     fprintf(f,st);
  2303.     fflush(f);
  2304. #endif
  2305.  
  2306.   if (dev_console && !external_print)
  2307.   {
  2308.     dev_console->put_string(st);
  2309.   }
  2310.  
  2311. #ifndef __MAC__
  2312.   else fprintf(stderr,"%s",st);
  2313. #endif
  2314. }
  2315.  
  2316.  
  2317. void game_getter(char *st, int max)
  2318. {
  2319.   if (!max) return ;
  2320.   max--;
  2321.   *st=0;
  2322.   if (dev_console && !external_print)
  2323.   {    
  2324.     dev_console->show();
  2325.     int t=0;
  2326.     event ev;
  2327.     do
  2328.     {
  2329.       get_event(ev,eh);
  2330.       if (ev.type==EV_KEY)
  2331.       {
  2332.         if (ev.key==JK_BACKSPACE)
  2333.         {
  2334.           if (t) 
  2335.           {
  2336.             dev_console->printf("%c",ev.key);
  2337.             t--;
  2338.             st--;
  2339.             *st=0;
  2340.             max++;
  2341.           }
  2342.         } else if (ev.key>=' ' && ev.key<='~')
  2343.         {
  2344.           dev_console->printf("%c",ev.key);
  2345.           *st=ev.key;
  2346.           t++;
  2347.           max--;
  2348.           st++;
  2349.           *st=0;
  2350.         }              
  2351.       }
  2352.       eh->flush_screen();
  2353.     } while (ev.type!=EV_KEY || ev.key!=JK_ENTER);    
  2354.     dprintf("\n");
  2355.   }
  2356.   else 
  2357.   {
  2358.     if (fgets(st,max,stdin))
  2359.     {
  2360.       if (*st)
  2361.         st[strlen(st)-1]=0;
  2362.     }
  2363.   }
  2364. }
  2365.  
  2366.  
  2367. void show_startup()
  2368. {
  2369.   show_verinfo(start_argc,start_argv);
  2370. }
  2371.  
  2372. char *get_line(int open_braces)
  2373. {
  2374.   char *line=(char *)jmalloc(1000,"lstring");
  2375.   fgets(line,1000,stdin);
  2376.  
  2377.   char prev=' ';
  2378.   for (char *s=line;*s && (prev!=' ' || *s!=';');s++)
  2379.   {
  2380.     prev=*s;
  2381.     if (*s=='(') open_braces++;
  2382.     else if (*s==')') open_braces--;
  2383.   }
  2384.   if (open_braces<0)    
  2385.     dprintf("\nToo many )'s\n");
  2386.   else if (open_braces>0)
  2387.   {
  2388.     char *s2=get_line(open_braces);
  2389.     line=(char *)jrealloc(line,strlen(line)+strlen(s2)+1,"lstring");
  2390.     strcat(line,s2);
  2391.     jfree(s2);    
  2392.   }  
  2393.   return line;
  2394. }
  2395.  
  2396. void check_for_upgrade(int argc, char **argv)
  2397. {
  2398.   for (int i=1;i<argc;i++)
  2399.     if (!strcmp(argv[i],"-upgrade"))
  2400.     {
  2401.       lisp_init(0xf000,0x30000);
  2402.       char *prog="(load \"lisp/upgrade.lsp\")",*cs;
  2403.       cs=prog;
  2404.       if (!eval(compile(cs)))
  2405.     dprintf("file does not exists : lisp/upgrade.lsp, cannot upgrade\n");
  2406.  
  2407.       exit(0);
  2408.     }        
  2409. }
  2410.  
  2411. void check_for_lisp(int argc, char **argv)
  2412. {
  2413.   for (int i=1;i<argc;i++)
  2414.   {
  2415.     if (!strcmp(argv[i],"-lisp"))
  2416.     {
  2417.       lisp_init(0xf000,0x30000);
  2418.  
  2419. #ifdef __WATCOMC__
  2420.       char *eof_char="CTRL-Z";
  2421. #else
  2422.       char *eof_char="CTRL-D";
  2423. #endif
  2424.       dprintf(
  2425.               " CLIVE (C) 1995 Jonathan Clark, all rights reserved\n"
  2426.               "   (C LISP interpreter and various extentions)\n"
  2427.               "Type (%s) to exit\n",eof_char);
  2428.  
  2429.       while (!feof(stdin))
  2430.       {
  2431.     dprintf("Lisp> ");
  2432.     char *l=get_line(0);
  2433.     char *s=l;
  2434.     while (*s)
  2435.     {
  2436.       void *prog=compile(s);
  2437.       l_user_stack.push(prog);
  2438.       while (*s==' ' || *s=='\t' || *s=='\r' || *s=='\n') s++;
  2439.       lprint(eval(prog));
  2440.       l_user_stack.pop(1);
  2441.     }
  2442.     jfree(l);
  2443.       }      
  2444.  
  2445.       dprintf("End of input : bye\n");
  2446.       exit(0);
  2447.     }
  2448.   }
  2449. }
  2450.  
  2451.  
  2452. void music_check()
  2453. {
  2454.   if (sound_avail&MUSIC_INITIALIZED)
  2455.   {
  2456.     if (current_song && !current_song->playing())
  2457.     {
  2458.       current_song->play();
  2459.       dprintf("song finished\n");
  2460.     }
  2461.     if (!current_song)
  2462.     {
  2463.  
  2464.       current_song=new song("music/intro.hmi");
  2465.       current_song->play(music_volume);
  2466.  
  2467.       /*      if (DEFINEDP(symbol_function(l_next_song)))  // if user function installed, call it to load up next song
  2468.               {
  2469.               int sp=current_space;
  2470.               current_space=PERM_SPACE;
  2471.               eval_function((lisp_symbol *)l_next_song,NULL);
  2472.               current_space=sp;
  2473.               } */
  2474.     } 
  2475.   }
  2476. }
  2477.  
  2478. void setup(int argc, char **argv);
  2479.  
  2480. void share_end();
  2481. void show_end();
  2482.  
  2483. void show_sell(int abortable);
  2484.  
  2485. extern pmenu *dev_menu;
  2486.  
  2487.  
  2488. extern int jmalloc_max_size;
  2489. extern int jmalloc_min_low_size;
  2490.  
  2491. extern int (*verify_file_fun)(char *,char *);
  2492.  
  2493. int registered_ok(char *filename, char *mode)
  2494. {
  2495.   if (registered) return 1;
  2496.  
  2497.   char name[256],*c;
  2498.   c=name;
  2499.   while (*filename) { *c=*(filename++); *c=toupper(*c); c++; } *c=0;
  2500.   if (strstr(name,"REGISTER"))
  2501.     return 0;
  2502.   else return 1;
  2503. }
  2504.  
  2505. void game_net_init(int argc, char **argv)
  2506. {
  2507.   int nonet=!net_init(argc, argv);
  2508.   if (nonet)
  2509.     dprintf("No network driver, or network driver returned failure\n");
  2510.   else 
  2511.   {
  2512.     set_file_opener(open_nfs_file);
  2513.     if (main_net_cfg && main_net_cfg->state==net_configuration::CLIENT)
  2514.     {
  2515.       if (set_file_server(net_server))
  2516.         start_running=1;
  2517.       else
  2518.       {
  2519.         dprintf("Unable to attach to server, quiting\n");
  2520.         exit(0);
  2521.       }
  2522.     } else
  2523.     {
  2524.       int i;
  2525.       for (i=1;i<argc-1;i++)
  2526.         if (!strcmp(argv[i],"-fs"))
  2527.           if (!set_file_server(argv[i+1]))
  2528.             dprintf("could not set defualt file server to %s\n",argv[i+1]);
  2529.     }
  2530.   }    
  2531.  
  2532. }
  2533.  
  2534. #ifdef __MAC__
  2535. //extern int PixMult;
  2536. #if 1
  2537. char cmdline[256];
  2538. #elif 1
  2539. char cmdline[] = "";
  2540. #elif 1
  2541. char cmdline[] = "abuse -server -a deathmat";
  2542. #else
  2543. char cmdline[] = "abuse -net 193.246.40.9";
  2544. #endif
  2545. char delims[] = " ";
  2546. char *tmp_argv[255];
  2547.  
  2548. void GetArgs(int &argc, char **(&argv))
  2549. {
  2550.   char *s;
  2551.  
  2552.   dprintf(    "Usage:\n"
  2553.       "  abuse [-options]\n\n"
  2554.       "  Options:\n"
  2555.       "    -server -a deathmat        become a server for deathmatch game\n"
  2556.       "    -net <dotted ip address>   connect to a server\n\n"
  2557.       "Options for mac:\n"
  2558.       "  Hold down <control> for single pixel mode\n"
  2559.       "  Hold down <option> for edit mode\n"
  2560.       "  Hold down <left shift> for double size mode\n\n"
  2561.       "If started with no command line options, networking will attempt\n"
  2562.       "  to search the local network for servers\n\n"
  2563.                 );
  2564.   dprintf("Enter command line:\n");
  2565.   gets(cmdline);
  2566.     
  2567.   argc = 0;
  2568.   argv = tmp_argv;
  2569.   s = strtok(cmdline, delims);
  2570.   while (s)
  2571.   {
  2572.     argv[argc] = s;
  2573.     argc++;
  2574.     s = strtok(0, delims);
  2575.   }
  2576.   argv[argc] = 0;
  2577. }
  2578.  
  2579. extern void InitMacScreen();
  2580. extern void QuitMacScreen();
  2581.  
  2582. #endif
  2583.  
  2584. int main(int argc, char **argv)
  2585. {
  2586. #ifdef __MAC__
  2587.   InitMacScreen();
  2588. #if 1
  2589.   //    if (!MacMenu())
  2590.   //        return 0;
  2591.  
  2592. #else
  2593.   unsigned char km[16];
  2594.  
  2595.   GetArgs(argc,argv);
  2596.     
  2597.   dprintf("Mac Options: ");
  2598.   GetKeys((unsigned long*)&km);
  2599.   if ((km[ 0x3a >>3] >> (0x3a & 7)) &1 != 0)
  2600.   {
  2601.     dev|=EDIT_MODE;    
  2602.     start_edit=1;
  2603.     start_running=1;
  2604.     disable_autolight=1;
  2605.     dprintf("Edit Mode...");
  2606.   }
  2607.   if ((km[ 0x3b >>3] >> (0x3b & 7)) &1 != 0)
  2608.   {
  2609.     PixMult = 1;
  2610.     dprintf("Single Pixel...");
  2611.   }
  2612.   else
  2613.   {
  2614.     PixMult = 2;
  2615.     dprintf("Double Pixel...");
  2616.   }
  2617.   if ((km[ 0x38 >>3] >> (0x38 & 7)) &1 != 0)
  2618.   {
  2619.     xres *= 2;  yres *= 2;
  2620.     dprintf("Double Size...");
  2621.   }
  2622.   dprintf("\n");
  2623.     
  2624.   if (tcpip.installed())
  2625.     dprintf( "Using %s\n", tcpip.name());
  2626. #endif
  2627. #endif
  2628.  
  2629.   start_argc=argc;
  2630.   start_argv=argv;
  2631.   
  2632.   { for (int i=0;i<argc;i++)
  2633.   {
  2634.     if (!strcmp(argv[i],"-cprint"))
  2635.       external_print=1;
  2636.     if (!strcmp(argv[i],"-min_low"))
  2637.     {
  2638.       i++;
  2639.       jmalloc_min_low_size=atoi(argv[i]);
  2640.     }
  2641.   }
  2642.   }
  2643.  
  2644.   set_dprinter(game_printer);
  2645.   set_dgetter(game_getter);
  2646.   set_no_space_handler(handle_no_space);
  2647.  
  2648.   setup(argc,argv);
  2649.  
  2650.   show_startup();
  2651.  
  2652.   //  jmalloc_max_size=0x150000;
  2653.   jmalloc_init(0x150000); 
  2654.   //  jmalloc_init(100000); 
  2655.  
  2656.   start_sound(argc,argv);
  2657.  
  2658. //#ifdef __MAC__
  2659.   //stat_man=new mac_status_manager();
  2660. //#else
  2661.   stat_man=new text_status_manager();
  2662. //#endif
  2663.   if (!get_option("-no_timer"))
  2664.   {
  2665.     timer_init();
  2666.   }
  2667.  
  2668.  
  2669.   if (!get_option("-share"))
  2670.   {
  2671.     jFILE *fp=new jFILE("register/micron.vcd","rb");
  2672.     if (!fp->open_failure())
  2673.     {
  2674.       spec_directory sd(fp);
  2675.       if (sd.find("Copyright (C) 1995 Crack dot Com, All Rights reserved"))
  2676.         registered=1;
  2677.     }
  2678.     delete fp;
  2679.   }
  2680.  
  2681.   verify_file_fun=registered_ok;
  2682.  
  2683.  
  2684.  
  2685.   jrand_init();
  2686.   jrand();  // so compiler doesn't complain
  2687.  
  2688.  
  2689.   set_spec_main_file("abuse.spe");
  2690.  
  2691.   if (getenv("ABUSE_PATH"))       // look to see if we are supposed to fetch the data elsewhere
  2692.     set_filename_prefix(getenv("ABUSE_PATH"));   
  2693.  
  2694.   if (getenv("ABUSE_SAVE_PATH"))       // look to see if we are supposed to fetch the data elsewhere
  2695.     set_save_filename_prefix(getenv("ABUSE_SAVE_PATH"));   
  2696.  
  2697.   check_for_lisp(argc,argv);
  2698.   check_for_upgrade(argc,argv);
  2699.  
  2700.   set_mode(VMODE_640x480,argc,argv);
  2701.  
  2702.   if (stat_man)
  2703.     delete stat_man;
  2704.   stat_man=new net_status_manager("art/loading.spe",
  2705.       413,428,608,451,
  2706.       54,104);
  2707.  
  2708.  
  2709.  
  2710.   do
  2711.   {
  2712.     if (main_net_cfg) 
  2713.     {
  2714.  
  2715.  
  2716.       if (!main_net_cfg->notify_reset())
  2717.       {
  2718.         if (!get_option("-no_timer"))
  2719.           timer_uninit();
  2720.         sound_uninit();
  2721.         exit(0);
  2722.       }
  2723.     }
  2724.  
  2725.     game_net_init(argc,argv);
  2726.     lisp_init(0x16000,0x94000);
  2727.     //  lisp_init(0x100000,0x10000);
  2728.  
  2729.     dev_init(argc,argv);
  2730.  
  2731.  
  2732.     game *g=new game(argc,argv);
  2733.  
  2734.     delete stat_man;
  2735.     stat_man=new net_status_manager("art/status.spe",
  2736.         295,203,304,366,
  2737.         46,222);
  2738.  
  2739.  
  2740.  
  2741.     dev_cont=new dev_controll();
  2742.     dev_cont->load_stuff();
  2743.  
  2744.  
  2745.  
  2746.     g->get_input();      // prime the net
  2747.  
  2748.     int xx;
  2749.     for (xx=1;xx<argc;xx++)
  2750.       if (!strcmp(argv[xx],"-server"))
  2751.       {
  2752.         xx++;
  2753.         if (!become_server(argv[xx]))
  2754.         {      
  2755.           dprintf("unable to become a server\n");
  2756.           exit(0);
  2757.         }
  2758.         xx=argc+1;
  2759.       }
  2760.  
  2761.     if (main_net_cfg) 
  2762.       wait_min_players();
  2763.  
  2764.     net_send(1);
  2765.     if (net_start())
  2766.     {
  2767.       g->step();                        // process all the objects in the 
  2768.       g->calc_speed();
  2769.       g->update_screen();               // redraw the screen with any changes
  2770.     }
  2771.  
  2772.     while (!g->done())
  2773.     {
  2774.       StartTime(0);//kill me
  2775.         
  2776.       StartTime(1);//kill me
  2777.       //      music_check();
  2778.  
  2779.       if (req_end)
  2780.       {
  2781.         delete current_level;
  2782.         current_level=NULL;
  2783.                 
  2784.         if (!registered)
  2785.           share_end();
  2786.         else show_end();
  2787.             
  2788.         the_game->set_state(MENU_STATE);
  2789.         req_end=0;
  2790.       }
  2791.       
  2792.  
  2793.       if (demo_man.current_state()==demo_manager::NORMAL)
  2794.       {
  2795.         net_receive();
  2796.       }
  2797.  
  2798.       if (req_name[0])            // see if a request for a level load was made during the last tick
  2799.       {
  2800.         //                    ProfilerDump("\pabuse.prof");  //prof    
  2801.         //                    ProfilerTerm();
  2802.         int show;
  2803.         if (!current_level)
  2804.           show=0;
  2805.         else if (strcmp(req_name,current_level->name()) && memcmp(req_name,"save",4)!=0)
  2806.           show=1;
  2807.         else show=0;
  2808.  
  2809.         if (show)
  2810.           show_stats();
  2811.         g->load_level(req_name);
  2812.         switch_mode(VMODE_320x200);
  2813.                recalc_local_view_space();
  2814.         if (show)
  2815.           end_stats();
  2816.  
  2817.         //                    ProfilerInit(collectDetailed, bestTimeBase, 2000, 200); //prof
  2818.         req_name[0]=0;
  2819.         g->draw(g->state==SCENE_STATE);
  2820.       }
  2821.  
  2822.       //    if (demo_man.current_state()!=demo_manager::PLAYING)
  2823.       g->get_input();
  2824.       
  2825.       if (demo_man.current_state()==demo_manager::NORMAL)
  2826.           net_send();
  2827.       else
  2828.           demo_man.do_inputs();
  2829.  
  2830.       service_net_request();
  2831.  
  2832.       DiffTime("  PreStuff",1); //kill me
  2833.       StartTime(2);    //kill me
  2834.             
  2835.       g->step();                        // process all the objects in the 
  2836.  
  2837.       DiffTime("  Step",2);  // kill me
  2838.       StartTime(3);  // kill me
  2839.       server_check();
  2840.  
  2841.       g->calc_speed();
  2842.       DiffTime("  MidStuff",3);  // kill me
  2843.       StartTime(4);  // kill me
  2844.       if (!req_name[0])                // see if a request for a level load was made during the last tick
  2845.         g->update_screen();               // redraw the screen with any changes
  2846.       DiffTime("  Update",4);  // kill me
  2847.  
  2848.       DiffTime("GameLoop",0);
  2849.     }
  2850.       switch_mode(VMODE_640x480);
  2851.     net_uninit();
  2852.  
  2853.     if (net_crcs)
  2854.     {
  2855.       net_crcs->clean_up();
  2856.       delete net_crcs;
  2857.       net_crcs=NULL;
  2858.     }
  2859.  
  2860.     delete chat;
  2861.  
  2862.     if (!registered)
  2863.       show_sell(0);
  2864.     else milli_wait(500);
  2865.  
  2866.  
  2867.     if (small_render) { delete small_render; small_render=NULL; }
  2868.  
  2869.     if (current_song) 
  2870.     { current_song->stop();
  2871.     delete current_song; 
  2872.     current_song=NULL; 
  2873.     }
  2874.  
  2875.  
  2876.     cash.empty();
  2877.  
  2878.  
  2879.     if (dev_console)
  2880.     {
  2881.       delete dev_console;
  2882.       dev_console=NULL;
  2883.     }
  2884.  
  2885.     if (dev_menu)
  2886.     {
  2887.       delete dev_menu;
  2888.       dev_menu=NULL;
  2889.     }
  2890.  
  2891.     delete g;
  2892.     if (old_pal) delete old_pal; old_pal=NULL;
  2893.     compiled_uninit();
  2894.     delete_all_lights();
  2895.     jfree(white_light_initial);
  2896.  
  2897.     for (int i=0;i<TTINTS;i++) jfree(tints[i]);
  2898.  
  2899.  
  2900.     dev_cleanup();
  2901.     delete dev_cont; dev_cont=NULL;
  2902.    
  2903.  
  2904.     if (!(main_net_cfg && main_net_cfg->restart_state()))
  2905.     {
  2906.       void *end_msg=make_find_symbol("end_msg");
  2907.       if (DEFINEDP(symbol_value(end_msg)))
  2908.         dprintf("%s\n",lstring_value(symbol_value(end_msg)));
  2909.     }
  2910.  
  2911.     lisp_uninit();
  2912.     sd_cache.clear();
  2913.  
  2914.     base->packet.packet_reset();
  2915.     mem_report("end.mem");
  2916.   } while (main_net_cfg && main_net_cfg->restart_state());
  2917.  
  2918.    close_graphics();
  2919.  
  2920.   if (main_net_cfg) { delete main_net_cfg; main_net_cfg=NULL; }
  2921.   set_filename_prefix(NULL);  // dealloc this mem if there was any
  2922.   set_save_filename_prefix(NULL);
  2923.  
  2924.   if (!get_option("-no_timer"))
  2925.     timer_uninit();
  2926.  
  2927.   mem_report("end.mem");
  2928.   jmalloc_uninit();
  2929.   l_user_stack.clean_up();
  2930.   l_ptr_stack.clean_up();
  2931.  
  2932.   sound_uninit();
  2933.  
  2934. #ifdef __MAC__
  2935.   QuitMacScreen();
  2936. #endif
  2937.  
  2938.   exit(0);
  2939.  
  2940.   return 0;  
  2941. }
  2942.  
  2943.